一、新特性
1.1 let 声明变量
var
声明的变量往往会越域,let
声明的变量有严格的局部作用域。// var声明的变量往往会越域
// let声明的变量有严格的局部作用域。
{
var a = 1;
let b = 2;
}
console.log(a); // 1
console.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); // 2
console.log(n); // Uncaught SyntaxError: Identifier 'n' has already been declared
var
会变量提升,let
不存在变量提升// var 会变量提升
// let 不存在变量提升
console.log(x); // undefined
var x = 10;
console.log(y); // Uncaught ReferenceError: Cannot access 'y' before initialization
let 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
通过数组解构解决:
```javascript
let 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. 多行字符串
```javascript
let 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. 插入表达式
```javascript
const 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 以前,我们无法给一个函数参数设置默认值,只能采用变通写法:
```javascript
function add(a, b) {
// 判断b是否为空,为空就给默认值 1
b = 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); // 2
fun(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,Jack
var 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 => {}));