一、新特性
1.1 let 声明变量
var声明的变量往往会越域,let声明的变量有严格的局部作用域。// var声明的变量往往会越域// let声明的变量有严格的局部作用域。{var a = 1;let b = 2;}console.log(a); // 1console.log(b); // Uncaught ReferenceError: b is not defined
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
```javascript// var可以声明多次// let只能声明一次var m = 1;var m = 2;let n = 3;let n = 4;console.log(m); // 2console.log(n); // Uncaught SyntaxError: Identifier 'n' has already been declared
var会变量提升,let不存在变量提升// var 会变量提升// let 不存在变量提升console.log(x); // undefinedvar x = 10;console.log(y); // Uncaught ReferenceError: Cannot access 'y' before initializationlet y = 20;
1.2 const 声明常量(只读变量)
// 声明之后不允许改变// 一旦声明必须初始化,否则会报错const a = 1;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
通过数组解构解决:```javascriptlet arr = [1, 2, 3];let [a, b, c] = arr;console.log(a, b, c); // 1 2 3
1.3.2 对象解构
普通方式:
const person = {name: "Jack",age: 21,language: ['java', 'js', 'css']}const name = person.name;const age = person.age;const language = person.language;console.log(name, age, language); // Jack 21 (3) ['java', 'js', 'css']
通过对象解构方式解决:
const person = {name: "Jack",age: 21,language: ['java', 'js', 'css']}const {name, age, language} = person;console.log(name, age, language); // Jack 21 (3) ['java', 'js', 'css']
扩展用法:如果想将name的值赋值给其他变量,可以使用如下方式,abc为新的变量名
const person = {name: "Jack",age: 21,language: ['java', 'js', 'css']}const {name:abc, age, language} = person;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
<a name="b2A6m"></a>### 1.4.2 字符串模板模板字符串相当于加强版的字符串,用反引号```,除了作为普通字符串,还可以用来定义多行字符串,还可以在字符串中加入变量和表达式。<a name="ziuYh"></a>#### 1. 多行字符串```javascriptlet ss = `<div><span>hello world</span></div>`;console.log(ss);

2. 字符串插入变量和表达式
可以通过将变量名写在${}中,${}中可以放入 JavaScript 表达式。
- 插入变量 ```javascript const person = { name: “Jack”, age: 21, language: [‘java’, ‘js’, ‘css’] }
let info = 我是${abc},今年${age}了;
console.log(info); // // 我是Jack,今年21了
2. 插入表达式```javascriptconst person = {name: "Jack",age: 21,language: ['java', 'js', 'css']}let info2 = `我是${abc},今年${age + 10}了`;console.log(info2); // 我是Jack,今年31了
- 调用函数 ```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了,我想说:这是一个函数
<a name="Q7D5T"></a>## 1.5 函数优化<a name="tfbYV"></a>### 1.5.1 函数参数默认值在 ES6 以前,我们无法给一个函数参数设置默认值,只能采用变通写法:```javascriptfunction add(a, b) {// 判断b是否为空,为空就给默认值 1b = b || 1;return a + b;}// 传一个参数console.log(add(10)); // 11
现在可以这样写:直接给参数写上默认值,没传就会自动使用默认值。
function add2(a, b = 1) {return a + b;}console.log(add2(20)); // 21
1.5.2 不定参数
不定参数用来表示不确定参数个数,形如:...变量名。由...加上一个具名参数标识符组成。具名参数只能放在参数列表的最后,并且有且只有一个不定参数。
function fun(...values) {console.log(values.length);}fun(1, 2); // 2fun(1, 2, 3, 4); // 4
1.5.3 箭头函数
ES6中定义函数的简写方式。
- 一个参数
普通方式:
var print = function (obj) {console.log(obj);}print("hello"); // hello
使用箭头函数方式:
var print = obj => console.log(obj);print("hello"); // hello
- 多个参数
普通方式:
var sum = function (a, b) {return a + b;}console.log(sum(1, 2)); // 3
箭头函数方式:
// 方法体只有一行var sum2 = (a, b) => a + b;console.log(sum2(2, 3)); // 5// 方法体有多行var sum3 = (a, b) => {c = a + b;return a + c;}console.log(sum3(2, 3)); // 7
1.5.4 箭头函数结合解构表达式
var hello2 = (param) => console.log("hello," + param.name);hello2(person); // hello,Jackvar hello3 = ({name}) => console.log("hello," + name);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 中。(第一层为深拷贝,第二层为浅拷贝)
示例:
const person = {name: "Jack",age: 21,language: ['java', 'js', 'css']}console.log(Object.keys(person)); // ['name', 'age', 'language']console.log(Object.values(person)); // ['Jack', 21, Array(3)]console.log(Object.entries(person)); // [Array(2), Array(2), Array(2)]// 0: (2) ['name', 'Jack']// 1: (2) ['age', 21]// 2: (2) ['language', Array(3)]
此Object.assign()方法的第一个参数是目标对象,后面的参数都是源对象。
const target = { a : 1 };const source1 = { b : 2 };const source2 = { c : 3 };// { a:1, b:2, c:3}Object.assign(target, source1, source2);console.log(target); // {a: 1, b: 2, c: 3}
1.6.2 声明对象简写
传统方式:
const name = "张三";const age = 13;// 传统声明方式const person1 = {age : age,name : age}
简写方式:
const name = "张三";const age = 13;// 简写方式const person2 = { age, name }
1.6.3 对象的函数属性简写
// 对象的函数属性简写let person3 = {"name": "jack",// 旧用法:eat : function (food) {console.log(this.name + "在吃" + food);},// 新的简写方式,但箭头函数中不能使用 this ,获取不到对象属性值eat2 : food => console.log(this.name + "在吃" + food),// 需要使用 对象名.属性名 获取属性值eat3 : food => console.log(person3.name + "在吃" + food),// 常用eat4(food) {console.log(this.name + "在吃" + food);}}person3.eat("香蕉"); // jack在吃香蕉person3.eat2("苹果"); // 在吃苹果person3.eat3("猕猴桃"); // jack在吃猕猴桃person3.eat4("橘子"); // jack在吃橘子
1.6.4 对象拓展运算符
拓展运算符(…) 用于取出参数对象所有可遍历属性然后拷贝到当前对象。
拷贝对象(深拷贝)
// 拷贝对象(深拷贝)let person4 = {name : "Amy",age : 15}let someone = { ...person4 }console.log(someone); // {name: 'Amy', age: 15}
合并对象
合并对象时,如果两个对象的字段名重复,后面对象字段值会覆盖前面对象的字段值。
// 合并对象
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对象,模拟后端返回数据:
user.json:
{ "id": 1, "name": "zhangsan", "password": "123456" }user_corse_1.json
{ "id": 10, "name": "chinese" }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 => {}));
