1.ECMAScript 6简介
1)什么是ECMAScript 6?
ECMAScript 6.0(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
2)ECMAScript和EJavaScript的的关系
一个常见的问题是,ECMAScript和JavaScript到底是什么关系?
要讲清楚这个问题,需要回顾历史。1996年11月,JavaScript的创造者Netscape公司,决定将JavaScript提交给国际标准化组织ECMA,希望这种语言能够成为国际标准。次年,ECMA发布262号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为ECMAScript,这个版本就是1.0版。
该标准从一开始就是针对JavaScript语言制定的,但是之所以不叫JavaScript,有两个原因。一是商标,Java是Sun公司的商标,根据授权协议,只有Netscape公司可以合法地使用JavaScript这个名字,且JavaScript本身也已经被Netscape公司注册为商标。二是想体现这门语言的制定者是ECMA,不是Netscape,这样有利于保证这门语言的开放性和中立性。
因此,ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现(另外的ECMAScript方言还有Jscript和ActionScript)。日常场合,这两个词是可以互换的。
2.ECMAScript 6 let和const关键字
1)let关键字
基本用法
ES6新增了let关键字,用来声明变量。它的用法类似于var。
let不允许重复声明变量
var num = 100;
var num = 200;
alert(num);//200
let num = 100;
let num =200;
alert(num)//Identifier 'num' has already been declared,直接报错
但是所声明的变量,仅在块级作用域内有效
{
var num = 100;
let num2 = 200; //形成局部作用域
alert(num2);//200
}
alert(num);//100
alert(num2);//num2 is not defined
上面代码在代码块之中,分别用let和var声明了两个变量。然后在代码块之外调用这两个变量,结果let声明的变量报错,var声明的变量返回了正确的值。这表明,let声明的变量只在它所在的代码块有效。
不能通过let声明和形参相同的变量
function show(num){
let num = 100;//Identifier 'num' has already been declared,会报错
alert(num);
}
show(200);
let声明变量不会提升
alert(num);//undefined
var num = 100;
alert(num);//Cannot access 'num' before initialization,直接就报错了
let num = 100;
【注】let声明的变量一定要在声明之后使用,否则报错。
暂时性死区TDZ
ES6规定在某个区块中, 一旦用let或const声明一个变量,那么这个区块就变成块级作用域,用let或const声明的变量就“绑定”这个区域,不再受外部的影响。 在该变量声明之前不可以用,在语法上我们叫这种情况为:暂时性死区 (temporal dead zone,简称 TDZ)。
var num = 100;
{
alert(num);//Cannot access 'num' before initialization,报错
let num = 200;
}
alert(num);
上面代码中,存在全局变量num,但是块级作用域内let又声明了一个局部变量num,导致后者绑定这个块级作用域,所以在let声明变量之前,使用num会报错。
2) const关键字
const关键字,用来声明一个只读的常量。
const与let类似,但是,但是,const常量一旦声明,常量将不能重新赋值!
const num = 100;
num;//100
num = 200;//TypeError: Assignment to constant variable.
上面代码表明改变常量的值会报错。
const声明的变量不得改变值,意味着,const一旦声明,就必须立即初始化,不能留到以后赋值!
const num;//SyntaxError: Missing initializer in const declaration
本质:const实际上保证的,并不是值不能改变,而是指向的那个内存地址不能改变。
const FOO = {name: "su"};
FOO.age = 20;
alert(FOO.age);
FOO = {name: "lin"};//Assignment to constant variable.
注意:为了和变量区分,一般常量用大写字母。
如:const PI = 3.14;
3.ECMAScript6 变量的结构赋值
1)数组的解构赋值
基本用法
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。
以前,赋值,只能直接指定值。
var x = 10, y = 20, z = 30;
ES解构赋值允许写成以下这样。可以理解为“模式匹配”。
var [x, y, z] = [10, 20, 30];
上面代码表示,可以从数组中提取值,按照对应位置,对变量赋值。下面是一些使用嵌套数组进行解构的例子。
var [x, [a, b], y] = [10, [20, ], 40];
alert(b + ", " + y);//10 40
var [a, , b] = [1, 2, 3];
alert(a); // 1
alert(b);// 3
var [a, b, ...c] = ['x'];
alert(a); // "x"
alert(b); // undefined
alert(c); // []
如果解构不成功,变量的值就等于undefined。
var [a] = [];
var [b, c] = [1];
alert(a);// undefined
alert(b);//1
alert(c); undefined
以上两种情况都属于解构不成功,a,c的值都会等于undefined。
2)解构赋值允许指定默认值
var [box = true] = [];
alert(box); // true
[x, y = 'b'] = ['a']; // x='a', y='b'
[x, y = 'b'] = ['a', undefined]; // x='a', y='b'
3)对象的解构赋值
var {name,age,sex} = {
name:"孙悟空",
age:500,
sex:"男"
}
alert(name);//孙悟空
alert(age);//500
alert(sex);//男
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
var {name,age,sex} = {
age:500,
sex:"男",
name:"孙悟空"
}
alert(name);//孙悟空
alert(age);//500
alert(sex);//男
var {name,age,sex} = {
age:500,
name:"孙悟空",
}
alert(name);//孙悟空
alert(age);//500
alert(sex);//undefined
上面代码的第一个例子,等号左边的两个变量的次序,与等号右边两个同名属性的次序不一致,但是对取值完全没有影响。第二个例子的变量没有对应的同名属性,导致取不到值,最后等于undefined。
对象解构赋值也可以指定默认值
var {x = 10} = {};
alert(x) // 10
var {x, y = 20} = {x: 10};
alert(x); // 10
alert(y);// 20
var {x:y = 30} = {};
alert(y);// 30
4)解构赋值的好处
交换变量的值
var num1 = 10;
var num2 = 20;
var tmp = num1;
num1 = num2;
num2 = tmp;
alert("num1:" + num1 + ", num2:" + num2);//num1:20, num2:10
函数可以同时返回多个结果
function showSelf({name,age = 40,sex = "男"}){
alert("我的名字叫" + name + ",今年" + age + "岁,性别是" + sex);
}
showSelf({
sex:"女",
age:30,
name:"黑寡妇"
})//我的名字叫黑寡妇,今年30岁,性别是女
函数传参的时候没有必要考虑函数的顺序
function fn( {sname,age} ){
return `大家好我叫${sname},我今年${age}岁了`;
}
alert( fn( {age:23,sname:"jack"} ) );//大家好我叫jack,我今年23岁了
*4.ECMAScript6 字符串的扩展
ES6中字符串模板(template string)使用反引号 表示,字符串模板中可以解析变量和函数,使用 ${ } 解析
传统的JavaScript语言,输出模板通常是这样写的。
var box = document.getElementById('box');
var val1 = 11, val2 = 22, val3 = 33;
box.innerHTML = '<ul><li>'+val1+'</li><li>'+val2+'</li><li>'+val3+'</li></ul>';
box.innerHTML = '<ul>'+
'<li>'+val1+'</li>'+
'<li>'+val2+'</li>'+
'<li>'+val3+'</li>'+
'</ul>';
上面这种写法相当繁琐不方便,我们使用ES6字符串模板解决了这个问题。
box.innerHTML = `
<ul>
<li>${val1}</li>
<li>${val2}</li>
<li>${val3}</li>
</ul>
`;
比如下面用ES6写的一个例子,就比较方便。
function showSelf({name, age = 40, sex = "男"}){
alert(`我的名字叫${name}, 我的年龄是${age}, 我的性别是${sex}`);
}
showSelf({
name: "贝吉塔",
age: 33,
sex: "男"
})//我的名字叫贝吉塔,我的年龄是33,我的性别是男