一、新特性

1.1 let 声明变量

  1. var声明的变量往往会越域,let声明的变量有严格的局部作用域。

    1. // var声明的变量往往会越域
    2. // let声明的变量有严格的局部作用域。
    3. {
    4. var a = 1;
    5. let b = 2;
    6. }
    7. console.log(a); // 1
    8. console.log(b); // Uncaught ReferenceError: b is not defined
  2. var可以声明多次,let只能声明一次 ```javascript // var可以声明多次 // let只能声明一次 var m = 1; var m = 2; let n = 3; // let n = 4;

console.log(m); // 2 console.log(n); // 3

  1. ```javascript
  2. // var可以声明多次
  3. // let只能声明一次
  4. var m = 1;
  5. var m = 2;
  6. let n = 3;
  7. let n = 4;
  8. console.log(m); // 2
  9. console.log(n); // Uncaught SyntaxError: Identifier 'n' has already been declared
  1. var会变量提升,let不存在变量提升
    1. // var 会变量提升
    2. // let 不存在变量提升
    3. console.log(x); // undefined
    4. var x = 10;
    5. console.log(y); // Uncaught ReferenceError: Cannot access 'y' before initialization
    6. let y = 20;

    1.2 const 声明常量(只读变量)

    1. // 声明之后不允许改变
    2. // 一旦声明必须初始化,否则会报错
    3. const a = 1;
    4. a = 3; // Uncaught TypeError: Assignment to constant variable.

    1.3 解构表达式

    1.3.1 数组解构

    普通方式: ```javascript let arr = [1, 2, 3];

let a = arr[0]; let b = arr[1]; let c = arr[2];

console.log(a, b, c); // 1 2 3

  1. 通过数组解构解决:
  2. ```javascript
  3. let arr = [1, 2, 3];
  4. let [a, b, c] = arr;
  5. console.log(a, b, c); // 1 2 3

1.3.2 对象解构

普通方式:

  1. const person = {
  2. name: "Jack",
  3. age: 21,
  4. language: ['java', 'js', 'css']
  5. }
  6. const name = person.name;
  7. const age = person.age;
  8. const language = person.language;
  9. console.log(name, age, language); // Jack 21 (3) ['java', 'js', 'css']
  1. 通过对象解构方式解决:
  1. const person = {
  2. name: "Jack",
  3. age: 21,
  4. language: ['java', 'js', 'css']
  5. }
  6. const {name, age, language} = person;
  7. console.log(name, age, language); // Jack 21 (3) ['java', 'js', 'css']
  1. 扩展用法:如果想将name的值赋值给其他变量,可以使用如下方式,abc为新的变量名
  1. const person = {
  2. name: "Jack",
  3. age: 21,
  4. language: ['java', 'js', 'css']
  5. }
  6. const {name:abc, age, language} = person;
  7. console.log(abc, age, language); // Jack 21 (3) ['java', 'js', 'css']

1.4 字符串扩展

1.4.1 几个新的API

ES6为字符串扩展了几个新的API:

  • include():返回布尔值,表示是否找到了参数字符串。
  • startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
  • endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。 ```javascript // 字符串扩展 let str = “hello.vue”;

console.log(str.startsWith(“hello”)); // true console.log(str.endsWith(“.vue”)); // true console.log(str.includes(“e”)); // true console.log(str.includes(“hello”)); // true

  1. <a name="b2A6m"></a>
  2. ### 1.4.2 字符串模板
  3. 模板字符串相当于加强版的字符串,用反引号```,除了作为普通字符串,还可以用来定义多行字符串,还可以在字符串中加入变量和表达式。
  4. <a name="ziuYh"></a>
  5. #### 1. 多行字符串
  6. ```javascript
  7. let ss = `<div>
  8. <span>hello world</span>
  9. </div>`;
  10. console.log(ss);

image.png

2. 字符串插入变量和表达式

可以通过将变量名写在${}中,${}中可以放入 JavaScript 表达式。

  1. 插入变量 ```javascript const person = { name: “Jack”, age: 21, language: [‘java’, ‘js’, ‘css’] }

let info = 我是${abc},今年${age}了;

console.log(info); // // 我是Jack,今年21了

  1. 2. 插入表达式
  2. ```javascript
  3. const person = {
  4. name: "Jack",
  5. age: 21,
  6. language: ['java', 'js', 'css']
  7. }
  8. let info2 = `我是${abc},今年${age + 10}了`;
  9. console.log(info2); // 我是Jack,今年31了
  1. 调用函数 ```javascript const person = { name: “Jack”, age: 21, language: [‘java’, ‘js’, ‘css’] }

function fun() { return “这是一个函数”; }

let info3 = 我是${abc},今年${age + 10}了,我想说:${fun()};
console.log(info3); // 我是Jack,今年31了,我想说:这是一个函数

  1. <a name="Q7D5T"></a>
  2. ## 1.5 函数优化
  3. <a name="tfbYV"></a>
  4. ### 1.5.1 函数参数默认值
  5. 在 ES6 以前,我们无法给一个函数参数设置默认值,只能采用变通写法:
  6. ```javascript
  7. function add(a, b) {
  8. // 判断b是否为空,为空就给默认值 1
  9. b = b || 1;
  10. return a + b;
  11. }
  12. // 传一个参数
  13. console.log(add(10)); // 11
  1. 现在可以这样写:直接给参数写上默认值,没传就会自动使用默认值。
  1. function add2(a, b = 1) {
  2. return a + b;
  3. }
  4. console.log(add2(20)); // 21

1.5.2 不定参数

不定参数用来表示不确定参数个数,形如:...变量名。由...加上一个具名参数标识符组成。具名参数只能放在参数列表的最后,并且有且只有一个不定参数。

  1. function fun(...values) {
  2. console.log(values.length);
  3. }
  4. fun(1, 2); // 2
  5. fun(1, 2, 3, 4); // 4

1.5.3 箭头函数

ES6中定义函数的简写方式。

  1. 一个参数

普通方式:

  1. var print = function (obj) {
  2. console.log(obj);
  3. }
  4. print("hello"); // hello

使用箭头函数方式:

  1. var print = obj => console.log(obj);
  2. print("hello"); // hello
  1. 多个参数

普通方式:

  1. var sum = function (a, b) {
  2. return a + b;
  3. }
  4. console.log(sum(1, 2)); // 3
  1. 箭头函数方式:
  1. // 方法体只有一行
  2. var sum2 = (a, b) => a + b;
  3. console.log(sum2(2, 3)); // 5
  4. // 方法体有多行
  5. var sum3 = (a, b) => {
  6. c = a + b;
  7. return a + c;
  8. }
  9. console.log(sum3(2, 3)); // 7

1.5.4 箭头函数结合解构表达式

  1. var hello2 = (param) => console.log("hello," + param.name);
  2. hello2(person); // hello,Jack
  3. var hello3 = ({name}) => console.log("hello," + name);
  4. hello3(person); // hello,Jack

1.6 对象优化

1.6.1 新增API

ES6 给 Object 拓展了许多新的方法,如:

  • keys(obj):获取对象的所有 key 形成的数组
  • values(obj):获取对象的所有 value 形成的数组
  • entries(obj):获取对象的所有 key 和 value 形成的二维数组。格式: [[k1,v1],[k2,v2],...]
  • assign(dest, ...src):将多个 src 对象的值拷贝到 dest 中。(第一层为深拷贝,第二层为浅拷贝)

示例:

  1. const person = {
  2. name: "Jack",
  3. age: 21,
  4. language: ['java', 'js', 'css']
  5. }
  6. console.log(Object.keys(person)); // ['name', 'age', 'language']
  7. console.log(Object.values(person)); // ['Jack', 21, Array(3)]
  8. console.log(Object.entries(person)); // [Array(2), Array(2), Array(2)]
  9. // 0: (2) ['name', 'Jack']
  10. // 1: (2) ['age', 21]
  11. // 2: (2) ['language', Array(3)]

Object.assign()方法的第一个参数是目标对象,后面的参数都是源对象。

  1. const target = { a : 1 };
  2. const source1 = { b : 2 };
  3. const source2 = { c : 3 };
  4. // { a:1, b:2, c:3}
  5. Object.assign(target, source1, source2);
  6. console.log(target); // {a: 1, b: 2, c: 3}

1.6.2 声明对象简写

传统方式:

  1. const name = "张三";
  2. const age = 13;
  3. // 传统声明方式
  4. const person1 = {
  5. age : age,
  6. name : age
  7. }

简写方式:

  1. const name = "张三";
  2. const age = 13;
  3. // 简写方式
  4. const person2 = { age, name }

1.6.3 对象的函数属性简写

  1. // 对象的函数属性简写
  2. let person3 = {
  3. "name": "jack",
  4. // 旧用法:
  5. eat : function (food) {
  6. console.log(this.name + "在吃" + food);
  7. },
  8. // 新的简写方式,但箭头函数中不能使用 this ,获取不到对象属性值
  9. eat2 : food => console.log(this.name + "在吃" + food),
  10. // 需要使用 对象名.属性名 获取属性值
  11. eat3 : food => console.log(person3.name + "在吃" + food),
  12. // 常用
  13. eat4(food) {
  14. console.log(this.name + "在吃" + food);
  15. }
  16. }
  17. person3.eat("香蕉"); // jack在吃香蕉
  18. person3.eat2("苹果"); // 在吃苹果
  19. person3.eat3("猕猴桃"); // jack在吃猕猴桃
  20. person3.eat4("橘子"); // jack在吃橘子

1.6.4 对象拓展运算符

拓展运算符(…) 用于取出参数对象所有可遍历属性然后拷贝到当前对象。

  1. 拷贝对象(深拷贝)

    1. // 拷贝对象(深拷贝)
    2. let person4 = {
    3. name : "Amy",
    4. age : 15
    5. }
    6. let someone = { ...person4 }
    7. console.log(someone); // {name: 'Amy', age: 15}
  2. 合并对象

合并对象时,如果两个对象的字段名重复,后面对象字段值会覆盖前面对象的字段值。

// 合并对象
let sex = { sex : 1 }
let heigth = { heigth : 175 }

let person5 = { ...sex, ...heigth }

console.log(person5);   // {sex: 1, heigth: 175}

1.7 数组新增map和reduce方法

1.7.1 map方法

map():接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。

let arr = ['1', '20', '-5', '3'];

arr1 = arr.map((item) => {
  return item * 2;
});
console.log(arr1);   // [2, 40, -10, 6]

// 或
arr2 = arr.map(item => item * 2);   // [2, 40, -10, 6]
console.log(arr2);

1.7.2 reduce方法

reduce(callback,[initialValue]):为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素。
其接受四个参数:

  • previousValue:初始值(或者上一次回调函数的返回值),
  • currentValue:当前元素值,
  • index:当前索引,
  • array:调用 reduce 的数组。
arr2 = [2, 40, -10, 6]
console.log(arr2); // [2, 40, -10, 6]

// 未指定初始值
let result = arr2.reduce((a, b) => {
    console.log("上一次处理后:" + a);
    console.log("当前正在处理:" + b);
    return a + b;
});

// 结果如下:

// 上一次处理后:2
// 当前正在处理:40
// 上一次处理后:42
// 当前正在处理:-10
// 上一次处理后:32
// 当前正在处理:6
arr3 = [2, 40, -10, 6]
console.log(arr3); // [2, 40, -10, 6]

// 指定初始值100
let result2 = arr3.reduce((a, b) => {
    console.log("上一次处理后:" + a);
    console.log("当前正在处理:" + b);
    return a + b;
}, 100);

// 执行结果如下

// 上一次处理后:100
// 当前正在处理:2
// 上一次处理后:102
// 当前正在处理:40
// 上一次处理后:142
// 当前正在处理:-10
// 上一次处理后:132
// 当前正在处理:6

1.8 Promise

构建三个json对象,模拟后端返回数据:

  1. user.json:

    {
     "id": 1,
     "name": "zhangsan",
     "password": "123456"
    }
    
  2. user_corse_1.json

    {
     "id": 10,
     "name": "chinese"
    }
    
  3. corse_score_10.json

    {
     "id": 100,
     "score": 90
    }
    

    1.8.1 循环嵌套式用法

    //回调函数嵌套的噩梦:层层嵌套。
    $.ajax({
     // 查询当前用户信息
     url: "mock/user.json",
     success(data) {
         console.log("查询用户:", data);    // {id: 1, name: 'zhangsan', password: '123456'}
         $.ajax({
             // 按照当前用户的id查询出他的课程
             url: `mock/user_corse_${data.id}.json`,
             success(data) {
                 console.log("查询到课程:", data);  // {id: 10, name: 'chinese'}
                 $.ajax({
                     // 按照当前课程id查出分数
                     url: `mock/corse_score_${data.id}.json`,
                     success(data) {
                       console.log("查询到分数:", data);  // {id: 100, score: 90}
                     }, error(error) {
                       console.log("出现异常了:" + error);
                     }
                 });
             }, error(error) {
               console.log("出现异常了:" + error);
             }
         });
     }, error(error) {
       console.log("出现异常了:" + error);
     }
    });
    

    1.8.2 使用Promise方式

    Promise可以封装异步操作。

    let p = new Promise((resolve,reject) => {
             // 异步操作
             $.ajax({
                 url: "mock/user.json",
                 success: function(data){
                     resolve(data);
                 },
                 error: function(err) {
                     reject(err);
                 }
             });
         });
    
         p.then((obj => {}));