变量

ES6中增加了let和const用来声明变量

  • var声明的变量可以重复声明、无法限制修改、没有if/for等块级作用域,只有函数作用域
  • let声明的变量不能重复声明,变量可以修改,块级作用域
  • const声明的常量不能重复声明,常量不允许修改,块级作用域

函数

箭头函数

ES6中增加了箭头函数,类似于lambda表达式 箭头函数里面的this指向上下文

  1. 如果只有一个参数,()可以省略
  2. 如果只有一个返回值,{}可以省略

箭头函数示例:

  1. // 原来的写法
  2. window.onload = function () {
  3. alert('abc');
  4. };
  5. // 箭头函数写法
  6. window.onload = ()=>{
  7. alert('abc');
  8. };
  9. // 原来的带参数函数写法
  10. let show = function(a,b){
  11. alert(a + b);
  12. };
  13. // 箭头函数的带参数写法
  14. let show = (a,b)=>{
  15. alert(a,b);
  16. };
  17. // 例如数组排序
  18. // 原来写法
  19. let arr = [12,5,6,4,22,8,10];
  20. arr.sort(funtion (n1, n2){
  21. return n1 - n2;
  22. });
  23. // 箭头函数写法
  24. let arr = [12,5,6,4,22,8,10];
  25. arr.sort((n1, n2)=>{
  26. return n1 - n2;
  27. });
  28. // 只有一个参数时小括号可以省略,只有一个return时大括号可以省略
  29. let show = funtion(a) {
  30. return a*2;
  31. };
  32. let show = a=>a*2;

函数的参数

参数的扩展/数组展开; 默认参数

参数扩展

  1. 收集剩余的参数```javascript function show(a, b, …args) { // ….除了a,b之外,函数的其余参数全部存放在args数组中

    1. // 存放剩余参数的变量Rest Parameter必须为最后一个参数,后面不能再有其他参数

    } ```

  2. 展开数组```javascript let arr = [1,2,3]; function show(a, b, c) { // ….. } show(…arr); // 将arr数组展开,对应到show的参数,等价于show(1,2,3)

// 将arr1、arr2数组中的值存入arr3数组中 // 数组展开后的效果,和直接把数组内容写在这里一样 let arr1 = [1,2,3]; let arr2 = [4,5,6]; let arr3 = […arr1, …arr2];

  1. <a name="2171d1b0"></a>
  2. #### 默认参数
  3. ```javascript
  4. function show(a, b=5, c=12){
  5. console.log(a, b, c);
  6. }
  7. show(99);

解构赋值

  1. 左右两边结构必须一样
  2. 右边必须是个东西
  3. 声明和赋值不能分开(必须在一句话里完成)
  1. // 原来的写法
  2. let arr = [1,2,3];
  3. let a = arr[0];
  4. let b = arr[1];
  5. let c = arr[2];
  6. // 解构赋值写法
  7. let [a, b, c] = arr;
  8. // JSON解构赋值,找json中对应名称的值,左右两边的结构同时为json
  9. let testJson = {a:1,b:2,c:3,d:4};
  10. let {a, c} = testJson;
  11. // 解构赋值时,左右两边必须结构一致
  12. let [{a,b}, [n1, n2, n3], d, e] = [{a:1, b:2, c:3}, [4, 5, 6], 7, 'aaa'];
  13. // 可以解析成任意粒度
  14. let [testJson, [n1, n2, n3], d, e] = [{a:1, b:2, c:3}, [4, 5, 6], 7, 'aaa'];
  15. // 可以在数组、json中使用...语法创建剩余变量数组
  16. let [first, ...rest] = [1, 2, 3, 4];
  17. // 仅赋值某几个变量
  18. let [ , second, , fourth] = [1, 2, 3, 4];

数组

map:一个对一个的进行映射 reduce:汇总,进来一堆,返回一个。 filter:过滤,通过返回值true或false决定是否保留 forEach:循环迭代

  1. // map示例
  2. // 返回数组对应每个分值是否及格
  3. let arr = [55,20,66,42,80,11,100];
  4. let result = arr.map(item => item>=60?'及格':'不及格');
  5. // reduce示例
  6. // 求最大值
  7. let arr = [12,5,6,49,23,42,55,14,35];
  8. // 循环 两两运算,tmp为中间结果,item为数组每项值,index为计算次数
  9. var result = arr.reduce(function (tmp, item, index) {
  10. return tmp > item ? tmp:item;
  11. });
  12. // 求平均值
  13. let arr = [12,5,6,49,23,42,55,14,35];
  14. // 循环 两两运算,tmp为中间结果,item为数组每项值,index为计算次数
  15. var result = arr.reduce(function (tmp, item, index) {
  16. if(index == arr.length-1) {
  17. return (tmp+item)/arr.length;
  18. }else{
  19. return tmp+item;
  20. }
  21. });
  22. // filter示例
  23. // 返回只含有被3整除的数字的数组
  24. let arr = [12,5,6,49,23,42,55,14,35];
  25. var result = arr.filter(item => item%3==0);
  26. // forEeach示例
  27. // forEach可以有一个参数item,也可以有两个参数index,item
  28. let arr = [12,5,6,49,23,42,55,14,35];
  29. arr.forEach(item => alert(item));

字符串

  1. 多了两个新方法
    • startsWith
    • endsWith
  2. 字符串模板
    • 直接把东西塞到字符串里面:$(东西)
    • 字符串中可以换行
  1. // 以前的写法
  2. let title = '标题';
  3. let content = '内容';
  4. let str = '<div>\
  5. <h1>' + title + '</h1>\
  6. <p>' + content + '</p>\
  7. </div>';
  8. // 字符串模板写法
  9. let title = '标题';
  10. let content = '内容';
  11. let str = `<div>
  12. <h1>${title}</h1>
  13. <p>${content}</p>
  14. </div>`;

面向对象

  1. 多了class关键字,使得构造器和类分开
  2. class里面直接加方法

原来的js类写法:

  1. // User既是类,又是构造方法,两者未分开
  2. function User(name, pass) {
  3. this.name = name;
  4. this.pass = pass;
  5. // 在构造方法中为类添加函数
  6. this.show=function (){
  7. alert(this.name + ' is ' + this.pass);
  8. }
  9. }
  10. // 使用原型链为类添加属性
  11. User.prototype.sex = '男';
  12. // 使用原型链为类增加函数
  13. User.prototype.showName = function (){
  14. alert(this.name);
  15. };
  16. User.prototype.showPass = function () {
  17. alert(this.pass);
  18. };
  19. // 静态属性
  20. User.level = 1;
  21. // 静态方法
  22. User.getInfo = function (){
  23. alert('静态方法');
  24. }
  25. // 调用静态方法
  26. User.getInfo();
  27. // 实例化对象调用
  28. var u1 = new User('zhangsan', '123456');
  29. u1.showName();
  30. u1.showPass();
  31. // 继承 (构造函数对象冒充 + 原型链 组合继承)
  32. function VipUser(name, pass, level) {
  33. // 单独用对象冒充可以继承构造函数里面的属性和方法,但是没法继承原型链上的属性和方法
  34. User.call(this, name, pass); // 使用call获取父类的构造方法(对象冒充实现继承)
  35. this.level = level;
  36. }
  37. // 原型链实现继承(单独用原型链继承,可以继承构造函数里面的属性和方法,也可以继承原型链上的属性和方法)
  38. // 但是单独用原型链实现的继承,在实例化子类的时候,没法给对象传参
  39. VipUser.prototype = new User(); // 将User的方法继承到VipUser原型上
  40. VipUser.prototype.constructor = VipUser; // 再将VipUser的构造方法还原成VipUser本身的构造方法
  41. VipUser.prototype.showLevel = function () {
  42. alert(this.level);
  43. }
  44. var v1 = new VipUser('testVip', '123456', 12);
  45. v1.showName();
  46. v1.showPass();
  47. v1.showLevel();

ES6的类写法:

  1. class User{
  2. constructor(name, pass) {
  3. this.name = name;
  4. this.pass = pass;
  5. }
  6. showName() {
  7. alert(this.name);
  8. }
  9. showPass() {
  10. alert(this.pass);
  11. }
  12. }
  13. var u1 = new User('zhangsan', '123456');
  14. u1.showName();
  15. u1.showPass();
  16. // 继承
  17. class VipUser extends User{
  18. constructor(name, pass, level) {
  19. super(name, pass);
  20. this.level = level;
  21. }
  22. showLevel(){
  23. alert(this.level);
  24. }
  25. }

面向对象在React框架中的应用

react框架: 1.组件化—-class; 2.JSX(JSX == babel == browser.js)

JSON

json标准写法

  1. 只能用双引号
  2. 所有的名字都必须用引号包起来
  1. JSON对象
    • JSON.stringify
    • JSON.parse
  2. 简写
    • 名字和值(key和value)一样的,留一个就行
    • 方法,冒号和function关键字一起省略 ```javascript // 原来的写法 var a = 1; var b = 2; var testJson = {“a”: a,
      1. "b": b,
      2. "c": 120,
      3. show : function (){
      4. // .....
      5. }
      6. };

// 简写 // key的双引号可以省略 let testJson = {a:a , b:b, c: 120} // 名称和值变量相同的,只需留一个 let testJson = {a, b, c:120} // 函数的冒号和function关键字可以省略 let testJson = {
show(){ //… } }

  1. <a name="Promise"></a>
  2. ## Promise
  3. > 异步:操作之间没有关系,同时进行多个操作。
  4. > 同步:同时只能做一件事。
  5. > 异步:代码更复杂。
  6. > 同步:代码简单
  7. 原始的同步异步代码,例如:
  8. ```javascript
  9. // 异步
  10. ajax("/banners", function(banner_data){
  11. ajax("/hotItems", function(hotItems_data){
  12. ajax("/slides", function(slides_data){
  13. //....
  14. },function(){
  15. alert('读取失败');
  16. });
  17. },function(){
  18. alert('读取失败');
  19. });
  20. },function(){
  21. alert('读取失败');
  22. });
  23. // 同步
  24. let banner_data = ajax_async('/banners');
  25. let hotItem_data = ajax_async('/hotItems');
  26. let slide_data = ajax_async('/slides');

Promise : 消除异步操作

用同步一样的方式,来书写异步代码

Promise中存放单一的ajax示例:

  1. // new一个Promise对象
  2. let p = new Promise(function (resolve, reject){
  3. // 异步代码
  4. // resolve -- 成功了
  5. // reject -- 失败了
  6. $.ajax({
  7. url: "arr.txt",
  8. dataType: 'json',
  9. success(arr){
  10. resolve(arr);
  11. },
  12. error(err){
  13. reject(err);
  14. }
  15. });
  16. });
  17. // 当Promise执行有结果时,调用then
  18. // then的参数中,第一个函数为成功时执行的函数,即resolve()
  19. // then的参数中,第二个函数为失败时执行的函数,即reject()
  20. p.then(function(arr) {
  21. alert('成功' + arr);
  22. }, function(err) {
  23. alert('失败' + err);
  24. });

Promise中存放多个ajax示例:

  1. // 第一个ajax
  2. let p1 = new Promise(function(resolve, reject){
  3. $.ajax({
  4. url:'arr.txt',
  5. dataType:'json',
  6. success(arr){
  7. resolve(arr);
  8. },
  9. error(err){
  10. reject(err);
  11. }
  12. });
  13. });
  14. // 第2个ajax
  15. let p2 = new Promise(function(resolve, reject){
  16. $.ajax({
  17. url:'testJson.txt',
  18. dataType:'json',
  19. success(testJson){
  20. resolve(testJson);
  21. },
  22. error(err){
  23. reject(err);
  24. }
  25. });
  26. });
  27. // 当所有的Promise都成功时,执行then
  28. Promise.all([p1,p2]).then(function(arr){
  29. // 成功后的arr为一个数组,数组中每项值为对应前面的Promise对象的结果
  30. let [result1, result2] = arr;
  31. alert("全都成功了");
  32. alert("p1的结果为" + result1);
  33. alert("p2的结果为" + result2)
  34. }, function(err){
  35. alert("至少一个失败了");
  36. });

对上面示例进行封装:

  1. function createPromise(url){
  2. return new Promise(function(resolve, reject){
  3. $.ajax({
  4. url,
  5. dataType:'json',
  6. success(testJson){
  7. resolve(testJson);
  8. },
  9. error(err){
  10. reject(err);
  11. }
  12. });
  13. }
  14. Promise.all([
  15. createPromise('arr.txt');
  16. createPromise('testJson.txt');
  17. ]).then(function(arr){
  18. let [result1, result2] = arr;
  19. alert("全都成功了");
  20. alert("p1的结果为" + result1);
  21. alert("p2的结果为" + result2)
  22. }, function(err){
  23. alert("至少一个失败了");
  24. });

Jquery本身带有的Promise

  1. // jQuery的ajax返回值就是一个Promise对象
  2. let p = $.ajax(url:'arr.txt', dataType:json);
  3. // 所以,Jquery的ajax可以直接写在Promise的all数组中
  4. Promise.all([
  5. $.ajax(url:'arr.txt', dataType:json);
  6. $.ajax(url:'testJson.txt', dataType:json);
  7. ]).then(function(arr){
  8. let [result1, result2] = arr;
  9. alert("全都成功了");
  10. alert("p1的结果为" + result1);
  11. alert("p2的结果为" + result2)
  12. }, function(err){
  13. alert("至少一个失败了");
  14. });

Promise的其他方法:

  1. // Promise.race,哪个执行的最快,就返回哪个结果,不管结果本身是成功状态还是失败状态
  2. Promise.race([
  3. $.ajax(url:'arr.txt', dataType:json);
  4. $.ajax(url:'testJson.txt', dataType:json);
  5. ]).then(function(arr){
  6. alert("成功了" + result1);
  7. }, function(err){
  8. alert("失败了");
  9. });

generator

generator是一种特殊的函数。 普通函数—-执行时一路执行到底; generator函数——执行的过程中间可以暂停

  1. // generator函数写法:function和函数名之间加星号
  2. // 可以写为 function* show(){...}; function *show(){...}; function * show(){...};
  3. // 不能写为 function*show(){...}
  4. // 不能写为箭头函数 *show()=>{....}
  5. function *show(){
  6. alert(1);
  7. alert(2);
  8. yield; // 使用yield关键字,放弃运行状态,运行到这里就停止
  9. alert(3);
  10. alert(4);
  11. }
  12. // 直接调用show()不会执行,返回一个generator对象
  13. let genObj1 = show();
  14. // next()执行到yield就停止
  15. genObj1.next();
  16. // yield暂停期间,可以执行其他代码
  17. alert(5);
  18. // 再次调用next()继续执行
  19. genObj1.next();

yield可以传参

  1. // 定义函数时,可以选择有参数函数
  2. function *show(num1, num2) {
  3. alert(`${num1},${num2}`);
  4. alert(1);
  5. // yield和上面的代码一起执行,然后暂停,下次next时传入的参数222返回给a
  6. let a = yield;
  7. alert(a);
  8. alert(2);
  9. }
  10. let genObj = show(1, 2); // 给函数传入参数num1,num2
  11. genObj.next(111); // 此处传入的111没有任何作用
  12. alert(5);
  13. genObj.next(222); // 此处传入的222将作为yield值,传递给let a

yield可以return

  1. function *show(){
  2. alert(1);
  3. yield 12;
  4. alert(2);
  5. return 55;
  6. }
  7. let genObj = show();
  8. let res1 = genObj.next(); // 可以获取到当前yield的返回值
  9. console.log(res1); // JSON类型:{value:12, done:false}
  10. let res2 = genObj.next(); // 最后一次的值是通过return获取
  11. console.log(res2); // JSON类型: {value:55, done:true}

yield传参和返回,伪代码示例:

  1. function *炒菜 (菜市场买回来的原材料){
  2. // ... 洗菜
  3. yield '洗好的菜';
  4. // ...切菜
  5. let 配料 = yield '切好的菜';
  6. // ...炒菜
  7. return '炒熟的菜';
  8. }
  9. let genObj = 炒菜();
  10. let res1 = genObj.next(); // 获取到'洗好的菜'。炒菜过程未完成,done=false
  11. // ...调制配料
  12. let res2 = genObj.next(); // 获取到'切好的菜'
  13. let res3 = genObj.next('配料'); // 将'配料'传进炒菜过程,最终获取到'炒熟的菜',炒菜过程完成,done=true

可以使用generator函数编写异步操作,类似Promise。

Promise适合场景:Promise中的所有异步ajax都需要读,一次读一堆;

generator适合场景:generator中间需要很多逻辑判断,后续操作需要根据前面的结果有条件操作;

ES7&8预览功能

数组

  • 多了includes方法:数组是否包含某个东西javascript let arr = [12,5,8]; alert(arr.includes(12));

  • keys/values/entries> keys:所有的key;

    values:所有的value; entries:所有的实体(即键值对)


for…of循环:循环iterator迭代器
for—-in循环:循环数组、JSON```javascript let arr = [12,5,8,32]; // for…in循环 for(let i in arr){ alert(i); // alert的i为arr的key:0,1,2,3, } // for…of循环 for(let i of arr) { alert(i); // alert的i为arr的value:12,5,8,32 } // json遍历 let testJson = {a: 12, b: 5, c:8}; for(let i in testJson) { alert(i); // alert的i为json的key:a,b,c } // JSON不是可迭代对象,不能使用for…of循环 for(let i of testJson) { alert(i);
}

  1. ```javascript
  2. let arr = [12, 5, 8, 22];
  3. // 使用for..of遍历arr的key
  4. for(let i of arr.keys()) {
  5. alert(i);
  6. }
  7. // 使用for...of遍历arr的value
  8. for(let i of arr.values()) {
  9. alert(i);
  10. }
  11. // 使用for...of遍历arr的键值对
  12. for(let [key,value] of arr.entries()) {
  13. alert(`${key}=${value}`);
  14. }

使用**来进行幂次运算

  1. alert('2的3次方=' (2**3));

字符串

ES7的字符串新增加了两个方法:

  1. padStart:左边补齐多少位
  2. padEnd:右边补齐多少位
  1. alert('abc'.padStart(5)); // 左边补2个空格凑足5位长度
  2. alert('123'.padStart(5,'0')); // 左边补2个0凑足5位长度
  3. alert('123'.padStart(5,'0')); // 右边补2个0凑足5位长度

语法容忍度

某些“错误”的语法正常执行

  • 数组语法容忍javascript // ES6功能,数组最后多了一个逗号,依然可以正常执行 let arr = [12, 5, 8, 6, ];

  • 函数参数语法容忍javascript // ES7功能,函数参数最后多了一个逗号,依然可以正常执行 function show(num1, num2, ){ //... }

async和awaite

用来替代generator yield。 原来的generator会被封装一个runner进行执行,async不再依赖外部的runner。 async 可以写成箭头函数。

  1. // 原来的generator的runner写法
  2. runner(function *readData(){
  3. let data1 = yield $.ajax({url: 'data/1.txt', dataType: 'json'});
  4. let data2 = yield $.ajax({url: 'data/2.txt', dataType: 'json'});
  5. let data2 = yield $.ajax({url: 'data/3.txt', dataType: 'json'});
  6. console.log(data1,data2,data3);
  7. });
  8. // async写法
  9. async function readData(){
  10. let data1 = await $.ajax({url: 'data/1.txt', dataType: 'json'});
  11. let data2 = await $.ajax({url: 'data/1.txt', dataType: 'json'});
  12. let data3 = await $.ajax({url: 'data/1.txt', dataType: 'json'});
  13. console.log(data1, data2, data3);
  14. }
  15. readData();
  16. //async的箭头函数写法
  17. let readData = async ()=>{
  18. //...
  19. }