02-ES6 变量、解构、对象、数组

1.变量
1.1 let特点(用于声明变量)

(1) 变量声明不会被提升,即在变量声明之前无法使用该变量 (2) 具有局部作用域,即let声明的变量只能在对应代码块中使用 (3) 不允许重复声明

1.2 const特点(用于声明常量)
const 用于声明一个常量 (1) 变量的声明不会被提升,即在变量声明之前无法使用该变量 (2) 不允许重复声明 (3) 具有局部作用域,即const声明的变量只能在对应代码块中使用。 (4) const声明的变量在声明的时候就要赋值,并且只能赋值一次,不能修改。

2. 解构
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。 解构得本质属于“模式匹配”,只要等号两边得模式相同,左边得变量就会被赋予对应得值。 如果解构不成功,变量得值就等于undefined。

2.1 数组解构
等号左边的变量放到中括号内部,匹配右侧数组中的元素。 (1) let [a,b,c] = [1,2,3]; console.log(a,b,c); //1,2,3 (2) let [a,b,c,d,e] = [1,2,3,[4,5],6]; console.log(a,b,c,d,e); //1,2,3,[4,5],6 (3) 不完全解构 let [a,b,c,[d],e] = [1,2,3,[4,5,6],7]; console.log(a,b,c,d,e); //1,2,3,[4],7 (4) 集合解构 使用...扩展运算符,用在=左边聚合作用,返回一个新数组 let [a, ...b] = [1,2,3]; console.log(a,b); //1,[2,3] (5) 默认值解构(当匹配值严格等于undefined时,默认值生效) let [a,b,c=6]=[4,5]; console.log(a,b,c); //2,5,6 let [a=1, b=2, c=3] = []; console.log(a,b,c); //1,2,3 (6) 默认值也可以是函数 function test(){ console.log("hello"); } let [a=test()] = [1]; console.log(a); //1 let [a] = [test()]; console.log(a); //"hello" undefiend //产生undefined的原因是函数test没有返回值。 (7) let arr = [1,2,3,4]; let [...a] = arr; console.log(a===arr); //false

2.2 对象解构
等号左边的变量放到大括号内部,匹配右侧对象中的元素。对象的属性没有次序,变量名必须与属性同名,才能取到正确的值。 (1) let {foo,bar} = {foo:"hello",bar:"world"}; console.log(foo,bar); //helloworld (2) 如果变量名和属性名不一致,需要重命名 let {foo:baz} = {foo:"hello",baz:"world"}; console.log(baz); //hello (3) 对象的解构赋值是下面形式的简写,前面属性名后面变量名 let {foo:foo,bar:bar} = {foo:"hello",bar:"world"}; (4) 嵌套结构 let obj = { p:["hello",{y:"world"}] } let {p:[a,{y:b}]} = obj; console.log(a,b); //hello world (5) 默认值结构 let {x:y=3}={}; console.log(y); //3面试题: const [a,b,c,...d]=[1,2,3,11,999]; const {e,f,f1,g,...h}={f:4,g:5,i:6,j:7}; console.log(a,b,c,d,e,f1,g,h); //1,2,3,[11,999],undefined,undefined,5,{i:6,j:7}

2.3 字符串解构
(1) 可以使用对象解构或者是数组解构,使用数组解构可以获取指定字符;使用对象解构可以获取实例属性方法。 let [a,b,c] = "hello"; console.log(a,b,c); //h e l (2) 将字符串转换为数组 let [...arr] = "hello"; console.log(arr); //["h","e","l","l","o"] (3) 使用对象解构 let {toString,valueOf,length}="hello"; //相当于把“hello”当成String基本包装器类型 console.log(toString,valueOf,length); //[Function: toString] [Function: valueOf] 5let str = "hello"; let { length, toString} = str; console.log(length === str.__proto__.length); //false console.log(toString === str.__proto__.toString); //true

2.4 数值解构
可以获取到数值包装器构造函数原型中指定的方法 let {toString,valueOf} = 10; console.log(toString,valueOf); //[Function: toString] [Function: valueOf]

2.5 布尔解构
可以获取到布尔包装器构造函数原型中指定得方法 let { valueOf } = true; console.log(valueOf); //[Function: valueOf]

3. 对象(ES6中对于Object的扩展主要是静态方法的扩展)
3.1 对象的简写
ES6中规定可以直接在对象中写入变量和函数作为对象的属性和方法,此时属性名为变量名,属性值为变量的值。 对象简写在未来的使用频率极其高。 let name = "zhangsan"; let age = 12; let gender = "male"; let obj = { name, age, gender }

3.2 对象API拓展
(1) Object.is(a,b); 判断a和b的值是否相等 类似于=== console.log(1===1); //true console.log(Object.is(1,1)); //true console.log(Object.is(1,2)); //false console.log(+0 === -0); //true console.log(Object.is(+0,-0)); //false console.log(NaN === NaN); //false console.log(Object.is(NaN,NaN)); //true (2) Object.assign(o, obj); 实现对象深复制、拷贝。第一个参数是目标对象,将obj的值复制给o let o = {}; let obj { name:"zhangsan", age: 12 } let result = Object.assign(o,obj); //把obj中的内容复制到o对象当中,并返回o对象 console.log(o); //{name:"zhangsan",age:12} console.log(result); //{name:"zhangsan",age: 12} console.log(o === result); //trueObject.assign(o,obj,obj1); 三个参数代表的是合并对象obj,obj1到o当中并返回o对象 let o = {}; let obj = { name:"zhangsan", age:12 } let obj1 = { name:"lisi", gender:1 } let result = Object.assign(o,obj,obj1); console.log(o); {name:'lisi',age:12,gender:1} console.log(result); //{name:'lisi',age:12,gender:1} let result1 = Object.assign(o,obj1,obj); console.log(result1); //{name:"zhangsan",age:12,gender:1} (3) Object.getPrototypeOf() 获取原型对象中的方法 let obj = { name:"", age:1 } console.log(obj.__proto__); //[Object: null prototype] {} console.log(obj.constructor.prototype); //[Object: null prototype] {} console.log(Object.getPrototypeOf(obj)); //[Object: null prototype] {} (3) 设置原型对象中的方法 Object.setPrototypeOf(obj,obj1) 设置obj的原型对象为obj1 let obj = { name:"zhangsan", age:12 } let obj1 = { gender:"male" } Object.setPrototypeOf(obj,obj1); console.log(obj.__proto__); //{ gender: "male"} console.log(obj.constructor.prototype); // [Object: null prototype] {} console.log(obj.constructor.prototype === obj1); //false console.log(Object.getPrototypeOf(obj)); //{ gender: "male"} (4) Object.keys() 返回对象属性名组成的数组 Object.values() 返回对象属性值组成的数组 Object.entries() 返回对象[属性名,属性值]组成的二维数组let obj = { name:'terry', age: 12 } //获取所有属性名组成的数组 console.log(Object.keys(obj)); //[ 'name', 'age'] //获取所有属性值组成的数组 console.log(Object.values(obj)); // [ 'terry', 12] //获取键值对组成的数组 console.log(Object.entries(obj)); //[ [ 'name','terry'], [ 'age', 12]]

4.数组(静态方法和实例方法都有所扩展)
4.1 扩展运算符
(1)... 用在=左边,聚合的作用(对象,数组的解构) let [a, ...b] = [1,2,3,4,5] console.log(a,b); //1,[2,3,4,5](2)... 用在=右边,展开(剥离)的作用 let obj1 = { name:"tom", age: 20 } let obj2 = { ...obj1, gender: "male", age:18 }

4.2 数组API
(1) Array.from(); 将类数组对像或其他数据类型(可迭代的)转成数组 ES5将类数组对象或其他数据类型(可迭代的)转成数组的方法: Array.prototype.slice.call("类数组对象",0); ES6转数组的方法: let arrObj = { 0:"tom", 1: "12", 3: "男", 4: ['jacky','terry'] length:4 } let arr = Array.from(arrObj); console.log(arr); //["tom","12","男",['jacky','terry']] 如果将上面代码中的length属性去掉,答案会是一个长度为0的空数组 然后再把代码改一下,就是具有length属性,但是对象的属性名不再是数字类型,而是其他字符串型的,代码如下 let arrObj = { name:"tom", age:12, sex:"男", friends:['jacky','terry'], length: 4 } let arr = Array.from(arrObj); console.log(arr); //[undefined, undefined, undefined, undefined] 由上可知,要将一个类数组对象转换为一个真正的数组,必须具备以下条件: a. 该类数组对象必须具有length属性,用于指定数组的长度。如果没有length属性,那嚒转换后的数组是一个空数组。 b. 该类数组对象的属性名必须为数值或字符串型的数字。该类数组对象的属性名可以加引号,也可以不加引号。 将字符串转换为数组: let str = "hello"; console.log(Array.from(str)); //['h','e','l','l','o'](2) Array.of()创建数组实例 实参就是数组的元素,为了解决new Array(10)传递一个数组,创建length 创建数组 let arr1 = new Array(1,2,3,4); console.log(arr1); //[1,2,3,4] let arr2 = new Array(3); console.log(arr2); //[<3 empty items>] let arr3 = Array.of(3); console.log(arr3); //[3] (3) Array.prototype.find( (item) => {}) find方法返回第一个满足条件的元素或者undefined,参数是回调函数 let arr = [1,2,3,2,3]; let result = arr.find((item) => { return item>2; }) console.log(result); //3 (4) Array.prototype.findIndex(); //参数回调函数 findIndex返回第一个满足条件的元素的索引或者-1 let arr = [1,2,3]; let result = arr.findIndex((item) => { return item>2; }) console.log(result); //2 (5) Array.prototype.includes(); includes是否包含某个元素,返回true/false let arr = [1,2,3] console.log(arr.includes(3)); //true (6) Array.prototype.fill() 用来填充数组,修改原数组 let arr = [1,2,3]; let result = arr.fill(4); console.log(arr,result, arr===result); //[4,4,4][4,4,4] true (7) Array.prototype.keys(); Array.prototype.values() Array.prototype.entries() //keys,values,entries变量当前是迭代器对象 let arr = [2,3,4]; let keys = arr.keys(); let values = arr.values(); let entries = arr.entries(); console.log(keys,values,entries); //Object [Array Iterator] {} Objcet [Array Iterator] {} Object [Array Iterator] {} 迭代器实现了Iterator接口,只要有实现了Iterator接口就可以for-of遍历

    推荐阅读