ES6 1
最近很多学生面试时候被问到ES6的问题,对于ES6这套标准,确实很多写法提供了便利的方式,我根据一个网站上得汇总,对每一条逐一的解释,这个过程也能发现自己对之前JS不足之处.
附:http://es6-features.org/#Constants
1.常量 Constants
在C语言里可以用const这个关键词来修饰定义出来的变量,即const int a = 10;,也可以使用宏,代替一部分不变的内容,但是在JS里,是没有常量的,这是ES6添加的新的内容
const PI = 3.141593; // ES6
这样PI就是一个常量了,跟C语言定义的方式类似,但是在之前的版本如果定义一个常量就不像ES6里这么简单,需要使用Object.defineProperty()方法对属性进行读写等操作设置
var stu = {
name:"你好",
age:20
}
Object.defineProperty(stu, "name", {
configurable: false,
writable: false,
enumerable: false,
value: null,
set: undefined,
get: undefined
})
这个方法需要三个参数:
参数1是需要设置的对象,这里就是stu;
参数2是要设置的属性名,
参数3:这里需要设置属性的操作,需要把对应的设置写成一个对象
实例代码里写了六个:
1.configurable:是否可以删除属性,是否可以修改属性的writable,enumerable的值;
2.writable:读写性设置,是否能对属性进行赋值,设置成false就变成只读属性;
3.enumerable:对象想进行遍历需要使用forin,for(var key in stu),如果属性name设置了enumerable为false之后,就不能使用forin进行遍历这条属性,这条属性也称为枚举设置
4.value:设置属性的默认值,即使对象的属性有初始值,还是以value值为主导
5.set:对应放一个方法,当属性被赋值的时候会被调用,但是如果writable设置成false的话,写这个会报错,报错内容 Cannot both specify accessors and a value or writable attribute,所以这个属性用得时候要看对应读写属性设置
6.get:这个跟set类似,获取属性值的时候会调用
当然这个还有Object.getOwnPropertyDescriptor()能获得属性对应设置内容
了解完这方法在看ES5的常量方法就不难理解
Object.defineProperty(window, "PI", {
value: 3.141593,
enumerable: true,
writable: false,
configurable: false
})
通过给window设置一个属性PI,这个属性不能修改,不能遍历,从而就实现了常量的设置,照比ES6,确实麻烦一些
2.作用域 Scoping
在使用JS的时候,应该会发现,for循环定义的i还能在循环外使用,但是函数定义的变量在函数外是使用不了的,这源于JS使用的是函数级作用域,而OC,C等使用的是块级作用域,也就是一个大括号就是一个作用域.
ES6有了变化,不在单一的使用var,而是可以使用let这个关键字,JS的let能限制变量的作用域,用法跟var类似,但还是有一些不同的地方
首先,let是没有变量提升的
console.log(a); // 报错,变量没有定义
let a = 100;
其次,let修饰的变量作用在块级作用域
for(let i = 0; i < 10; i++) {
console.log(i);
}
console.log(i); // 报错,变量没定义
之前作用域最闹心的问题就是闭包,就拿闭包举个例子,循环给标签绑定点击事件,打印下标,解决方法还有别的,这里就说闭包这种
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
// ES5 代码
var divs = document.getElementsByTagName("div");
for(var i = 0; i < divs.length; i++) {
(function(index) {
divs[index].onclick = function() {
alert(index);
}
})(i)
}
因为i还是函数作用域,所以要通过闭包改变i的作用范围,用index进行替换,很麻烦,而且不好理解,但是到了ES6之后,有了let,这种写法就可以不用了
// ES6 代码
var divs = document.getElementsByTagName("div");
for(let i = 0; i < divs.length; i++) {
divs[i].onclick = function() {
alert(i);
}
}
效果是一样的,let完全限制了i的使用范围,解决了之前的问题,代码确实越来越好理解
JS里在使用变量和函数的时候要注意代码的规范,使用变量和函数之前,一定要要先定义,这样就不会出现变量提升等跟常规C语言不同的代码书写习惯,JS在ES6里还是以函数级作用域为主,即使加了{},也有效果但是本质还是函数级作用域
3.箭头函数 Arrow Functions
在ES6里新添加了这种箭头操作符,这种操作符不是JS原创的,在JAVA和C#里都有这种操作符,这种操作符称为Lambda表达式,本质上就是一个匿名函数,简化匿名函数书写
var arr = ["宋江", "卢俊义", "吴用", "公孙胜", "关胜", "林冲"];
arr.forEach(function(value, index) {
console.log(index + value);
})
这是JS里对数组遍历的forEach方法,里面需要加一个回调函数,这个函数就是一个匿名的函数,可以对这个函数用=>的方法进行简写
arr.forEach((value, index) => {
console.log(value+index);
})
照比之前写法,这种箭头函数写法就是去掉了function,形参和大括号之间用=>连接,其实就是一个匿名函数
在很多需要匿名函数的地方都可以使用这种方法,比如数组的map方法,也能使用箭头函数来替换
// ES5
var newArr = arr.map(function(value, index){
return value + index;
})
// ES6
var newArr = arr.map((value, index) => value + index);
如果是给标签添加事件也可以
div.onclick = ()=>{
console.log(111);
}
如果需要event就在括号里填上event,但是这么写完之后,可能大括号里没有代码提示,那就相信自己吧