ES6新增语法(一)
let的使用
下方的代码知识演示用的demo,正式项目命名还是要规范的
-
let和var是有区别的,let设计之初的目的就是let声明的变量只在块作用域中生效。
if(false){ var num1 = 1; } console.log(num1);//undefined 这里是变量的提升,所以没有直接抛出错误,而是显示未赋值 if(true){ let num2 = 1; } console.log(num2); //报错,因为let是有块级作用于下才能调用的,所以会找不到num2这个变量,就会抛出错误
-
let声明不会被提升
console.log(c);//报错,因为变量c不会被提升,访问不到c变量 let c = 30;
-
在循环中则会在每个小的子作用域,声明一个新的只在当前生效的变量。
var arr = []; for (let i = 0; i < 2; i++) { // arr[0]=function // arr[1]=function arr[i] = function () { console.log(i); } } arr[0]();// 0 arr[1]();// 1
if(true){ let a = 0; if(true){ // let a = 2; console.log(a);//答案是多少?答案是0 } }
-
let会造成暂时性死区
var num = 40; if(true){ console.log(num);//报错 let num = 10; }
这里是因为只要块级作用域内存在 let 命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。let还不能变量提升造成在声明前就进行使用的话就会导致js引擎抛出错误。
ES6明确规定,如果区块中存在 let 和 const 命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
-
let和const都不能进行重复声明!
-
let的变量在全局作用于下声明,也不会把变成window下的属性。
const的使用
-
const
和let
一样都是有块级作用域的 -
const的同时必须赋值,如果不赋值,js引擎会抛出错误
const num;//直接报错 console.log(num);
-
常量的值不能修改,引用的数据类型的话,只要引用的地址没有发生改变就还可以进行修改值的。
const studentName = ['zhangsan','lisi','wanghong']; studentName = ['zhuibangde'];//这几会发生引用的地址发生改变,是规则不允许的!会抛出错误
但是我们可以这么修改,只对内容进行修改,不改变引用地址(指针),
const studentName = ['zhangsan','lisi','wanghong']; studentName[1]='mingming'; console.log(studentName[1]);
解构
数组解构
-
数组的解构我们可以用来对数组中的内容进行赋值
let arr=[1,2,3]; let[a,b,c,d,e]=arr; console.log(a,b,c);//1,2,3
-
如果没有解构成功返回undefined,结构赋值
let arr=[1,2,3]; let [a,b] = arr; let [, , c] = arr; console.log(a); console.log(b); console.log(c);
-
也可以用来重新覆盖某个值
let arr = [1,2,3] let a=10; let b=100; [a,b] = arr; console.log(a);//1 console.log(b);//2
对象的解构
-
变量的名字与对象中的key值去匹配,匹配成功后返回值(默认)
let person = { uname:'zhangsan', age:18, sex:'男', phone:{ number:888 } }; let{uname,sex,age}=person;
-
可以通过对已存在的变量进行赋值
let person = { uname:'zhangsan', age:18, sex:'男', phone:{ number:888 } } let firstName = 'zhangsanfeng'; let oldYear = 30; ({ uname:firstName, age:oldYear }=person); console.log(firstName); console.log(oldYear);
-
解构时候的把对象值赋给不同名的变量
let obj = { uname:'lili', sex:18 } let {uname:names,sex:male} = obj;//uname为对象中的键名,names是要把对象中键名为uname的键值传给names console.log(names,male);
解构的应用
-
变量可以直接对值进行互换,不在需要中间变量
let a = 1; let b = 2; [a,b] = [b,a]; console.log(a,b);//2,1
-
可以用结构方式接受函数的返回值
//返回数组运行结果 function fun1(){ return [1,2,3]; } let arr=[a,b,c]=fun1(); console.log(arr);//[1, 2, 3] console.log(a,b,c);//1,2,3 // 返回对象 function fun2(){ return { num1:1, num2:2 } } let obj={ num1, num2 }=fun2(); console.log(num1);//1 console.log(num2);//2 console.log(obj);//{num1: 1, num2: 2}
-
还可以用解构方式把数组里每一项作为参数传入函数(必须形参是解构的模式,实参是可以解构赋值的对象)
function fun3([a,b,c]){ console.log(a,b,c); }; fun3([1,2,3]); ///实参是可以解构赋值的对象 function fun4({a,b,c}){ console.log(a,b,c); } fun4({a:1,b:2,c:3}); //也可以部分用结构,部分用实际的参数 function fun5(num,{a,b,c}){ console.log(num,a,b,c); } fun5(100,{a:1,b:2,c:3});
箭头函数
- 箭头函数的用法
()=>{};//():代表是函数; =>:必须要的符号,指向哪一个代码块;{}:函数体
var fn = () => {}//代表把一个函数赋值给fn
-
箭头函数的参数
//箭头函数只有一个参数时候,可以忽略括号 let fn = name =>{ console.log(`你好${name}`) } fn('lili');
-
箭头函数的返回值
//如果执行体只有一行代码,并且执行的代码就是返回值,那么就可以省略大括号不必写return let fn1 = name => name + '123'; console.log(fn1('明明'));//明明123
-
箭头函数的this指向问题,他指向的永远是自己作用域所在的执行上下文,如果在自己自行上下文没有this则会向作用域的上方查找this.
function fn3() { console.log(this);//this 指向 是obj对象 return () => { console.log(this);//this 指向 的是箭头函数定义的位置,那么这个箭头函数定义在fn里面,而这个fn指向是的全局对象(浏览器指向window,node指向global),如果fn3没有改变this指向,那么该箭头函数的this也是指向的this. } } var resFn = fn3(); resFn();//window或者global
剩余参数
剩余参数语法允许我们将一个不定数量的参数表示为一个数组。
如果函数的最后一个命名参数以...
为前缀,则它将成为一个由剩余参数组成的真数组,其中从0
(包括)到theArgs.length
(排除)的元素由传递给函数的实际参数提供。
function fun4(...args) {
return args;
}
console.log(fun4(1,2,3));//[1,2,3]
function fun4(...args) {
let [a,b,c] = args;
return a + b +c;
}
console.log(fun4(1,2,3));//6
- 剩余参数和
arguments
对象之间的区别主要有三个:- 剩余参数只包含那些没有对应形参的实参,而
arguments
对象包含了传给函数的所有实参。 arguments
对象不是一个真正的数组是类数组,而剩余参数是真正的Array
实例,也就是说你能够在它上面直接使用所有的数组方法,比如sort
,map
,forEach
或pop
。arguments
对象还有一些附加的属性 (如callee
属性)。
- 剩余参数只包含那些没有对应形参的实参,而