在ES3中,没有常量这一说。
在ES5中,通过变量的定义只读,不可修改。
在ES6中,用const定义常量也是只读,不可修改。
举个例子,设置圆周率PI的值:
//es5写法
Object.defineProperty(window,'PI',{
value:3.1415926,//定义属性值
writable:false,//是否只读
})
//es6写法
const PI = 3.1415926;
console.log(PI)
总结:es5和es6的常量在运行时是不一样的,es5中常量赋值不会成功,也不会报错
ES5和ES6区别
举个例子:
//ES5作用域
var callbacks = [];
for(var i = 0; i <= 2; i++){
callbacks[i] = function() {
return i * 2
}
}
console.table([
callbacks[0](),
callbacks[1](),
callbacks[2]()
])
//ES6作用域
const callbacks2 = [];
for(let j = 0; j <= 2; j++){
callbacks2[j] = function(){
return j * 2
}
}
console.table([
callbacks2[0](),
callbacks2[1](),
callbacks2[2]()
])
额。。。值得注意的是,在ES5作用域中返回的结果都会6,var i = 0是全局中的变量, return i * 2 返回的不是一个值,而是一个表达式 ,所以callbacks 内部 function 形成一个闭包,但闭包内并没有声明内部的 i 变量,因此 i 变量从for 循环内声明的全局变量中取得,从全局变量中取得时的 i=3 是最终计算量。
而在ES6中 let申明使每次产生新的作用域 (块级作用域) 也就是把当前的j值保存下来,供内部作用域使用,不再担心闭包的副作用,所以不出现上述情况。
再举个例子,如果我们用块作用域给代码做隔离:
//ES5语法
;((function(){
var foo = function(){
return 1
};
console.log("函数foo()===1",foo()===1);
;((function(){
var foo = function(){
return 2
};
console.log("函数foo()===2",foo()===2);
})())
})())
//ES6语法
{
function foo(){
return 1
}
console.log("函数foo()===1",foo()===1);
{
function foo(){
return 2
}
console.log("函数foo()===2",foo()===2);
}
}
总结:ES5 中通过立即执行函数来创建块级作用域,ES6中可直接使用花括号来创建块级作用域
题外话:这里关于let和var、const区别:
使用var声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象;
使用let声明的变量,其作用域为该语句所在的代码块内,不存在变量提升;
使用const声明的是常量,在后面出现的代码中不能再修改该常量的值。
知乎,关于JavaScript中var、let、const区别?
ES3、ES5普通函数 : function a(){}
ES6箭头函数: () => {};
举个例子,通过map方法将原数组“映射”成对应的新数组:
//ES3,ES5写法
var a = [1,2,3,4,5];
var b = a.map(function(i) {
return i + 1
});
console.log(a,b);
//ES6写法
let a = [1,2,3,4,5];
let b = a.map(i => i + 1)
console.log(a,b);
总结:箭头函数和普通函数在再于let的绑定;当函数只有一个参数时,可以省略括号,但函数只返回一个值时,可以省略花括号
然后~这里还要说下关于箭头函数this指向问题。
注意:普通函数this指向:是该函数被调用的的对象,箭头函数:定义时this的指向(指向全局window对象)
再举个例子:
//ES3,ES5
function foo(){
this.a = 'a';
this.b = 'b';
this.c = {
a: 'a+',
b: function() {
return this.a
}
}
}
console.log(new foo().c.b());
//ES6
function foo2(){
this.a = 'a';
this.b = 'b';
this.c = {
a:'a+',
b:() => {
return this.a
}
}
}
console.log(new foo2().c.b());
这里可以看到实例化一个foo对象后,调用c对象里面的b方法。在普通函数this指向的是该函数被调用的对象,也就是c对象,所以输出a+。而在ES6箭头函数中,函数体内的this.a是构造函数foo定义的this.a,所以输出a。