let 和 const
作为代替var的两个变量。
他们具有以下共同点:
变量不提升
不允许重复声明
块级作用域
let具有自己独特的特性:暂时性死区
只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
下面的代码,因为块内声明了let
变量tmp,tem绑定了这个块。因此tmp变量声明前对变量赋值时,并没有按照常识,赋值给外层,而是报错。
var tmp = 123;
if (true) {
tmp = 'abc'; // tmp is not defined
let tmp;
}
const具有自己独特的特性:
值类型的数据不可改动
引用类型,指针不可改动,内部可改动
声明const同时必须初始化(因为要锁定内存位置)
创建完全不可改动const
实际和const无关,换成var依然无法修改
Object.deepFreeze = function(obj) {
var propNames = Object.getOwnPropertyNames(obj)
propNames.forEach(function(name) {
var prop = obj[name]
if (typeof prop == 'object' && prop != null) {
Object.deepFreeze(prop)
}
})
return Object.freeze(obj)
}
const a = Object.deepFreeze({a:1,b:{c:2}})
箭头函数
一种更灵活的方式去声明一个函数,并且具有明确的不可改变的this指向
不同的声明方式:
以下为根据参数数量不同,以及语句数量不同来以不同的方式声明箭头函数
根据参数数量不同:
// 零个参数
const zero = () => {…}
// 一个参数
const one = arg => {…}
// 多个参数
const n = (arg1, arg2, …argn) => {...}
根据语句数量不同:
// 一条语句(一条语句默认行为:返回值为该语句执行结果)
const one = (arg1,arg2) => arg1 + arg2
// 如果是一条语句,且返回的是个对象字面量
const oneJson = arg => ({ a:arg })
// 多条语句(可以没有返回值)
(arg1,arg2) => {
alert(arg1 + arg2)
}
不同的参数对象引用方式
const headAndTail = (head, ...tail) => [head, tail];
headAndTail(1, 2, 3, 4, 5);
// [1,[2,3,4,5]]
两个特性
this锁定了父级作用域的上下文,不是调用时当前作用域上下文。且不能用apply、call、bind去改变。所以当对this的指向有明确的指向时应避免使用箭头函数。例如vue的计算属性等。
// 锁定为上一层对象
a = 2
const obj = {
a: 1,
b: () => console.log(this.a)
}
obj.b()
// 2
// 不能改变
obj.b.call(obj)
// 2
不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误