ES6系列学习(1)
来源:
https://www.bilibili.com/video/av47304735/?p=1
https://www.youtube.com/watch?v=5s35h_6v4ZI&list=PLCRqr1mERvdJ0IZMD1U4oSB7k0gyAjyIx
1.var let const
const只是保证引用地址不变,所以变量里面内容可变。
const person = {
name : 'Jelly',
age:20
}
//修改引用地址,会报错
person = {name:'bool'}
//修改对象里面属性,但是引用地址不变
person.age = 21
person
{
name:'Jelly',
age:21
}
2.我们延伸出:对象属性描述符、对象的扩展、密封和冻结。
对象属性描述符
对象是一个属性集合,对象的基本特征是属性名(name)和属性值(value)。ES5 增加了属性描述符,可以更细腻的控制属性的不同操作。属性描述符有 configurable、writable 和 enumerable。
属性描述符通常和 Object.defineProperty/Object.defineProperties 一起使用来定义属性,它也会受到诸如 Object.freeze/Object.seal 等方法改变。
1.configurable 当且仅当 configurable 为 true 时,该属性才能够被改变,也能够被删除(delete),默认为 false
var obj = {}
Object.defineProperty(obj, 'name', {
value: 'John'
})
// 不能 delete
delete obj.name // false
Object.defineProperty(obj, 'name', {
configurable: true,
value: 'John'
})
// 可以delete
delete obj.name // true
2.writable 当且仅当 writable 为 true 时,该属性才能被赋值运算符(=)改变,默认为 false
var obj = {}
Object.defineProperty(obj, 'name', {
value: 'John'
})
obj.name = 'Backus' // 修改不起作用,仍然是 John,严格模式中会报错阻止修改
Object.defineProperty(obj, 'name', {
writable: true,
value: 'John'
})
obj.name = 'Backus' // 被改为了 backus
3.enumerable 当且仅当 enumerable 为 true 时,该属性才能够出现在对象的枚举属性(for in)中,默认为 false
var obj = {}
Object.defineProperty(obj, 'name', {
value: 'John'
})
// 不能遍历
for (var a in obj) {
console.log(a) // 无输出
}
Object.defineProperty(obj, 'name', {
enumerable: true,
value: 'John'
})
// 可以遍历
for (var a in obj) {
console.log(a) // 输出 "name"
}
ES6 的 Object.keys 只返回 enumerable=true 的属性
var obj = {name: 'John'}
Object.defineProperty(obj, 'name', {
value: 'Backus',
enumerable: true
})
Object.defineProperty(obj, 'age', {
value: 30,
enumerable: false
})
Object.keys(obj) // ['name']
可以通过 propertyIsEnumerable 方法判断属性的 enumerable 值
obj.propertyIsEnumerable('name') // true
obj.propertyIsEnumerable('age') // false
4.使用 ES3(传统的) JSON 方式定义对象,其 configurable/writable/enumerable 默认都是 true,使用 ES5 的 Object.defineProperty/Object.defineProperties 方式定义对象,其 configurable/writable/enumerable 默认都是 false
//ES3定义
var obj = {name: 'John', age: 30}
// configurable
delete obj.name // true
// writable
obj.age = 32 // true
// enumerable
for (var a in obj) {
console.log(a) // age
}
//ES5定义
var obj = {}
Object.defineProperty(obj, 'name', {
value: 'John'
})
Object.defineProperty(obj, 'age', {
value: 33
})
// configurable
delete obj.name // false
// writable
obj.age = 32 // false
// enumerable
for (var a in obj) {
console.log(a) // 无输出,不能遍历
}
和属性描述符相关的几个函数
1.Object.defineProperty
2.Object.defineProperties
3.Object.getOwnPropertyDescriptor
//Object.defineProperty
var obj = {}
Object.defineProperty(obj, 'name', {
value: 'John'
})
Object.defineProperty(obj, 'age', {
value: 33
})
//Object.defineProperties,Object.defineProperties 批量定制对象属性,内部其实循环方式调用 Object.defineProperty
Object.defineProperties(obj, {
name: {
value: 'John',
writable: true
},
age: {
value: 30,
enmuerable: true
}
})
//Object.getOwnPropertyDescriptor 返回该对象某属性的描述器,描述器自身是一个对象
var obj = {}
Object.defineProperty(obj, 'name', {
value: 'Backus',
writable: true,
enumerable: true
})
var des = Object.getOwnPropertyDescriptor(obj, 'name')
console.log(des)
输出如图
参考文章:http://www.cnblogs.com/snandy/p/5276578.html
ES5对象的扩展、密封和冻结
ES5对象的扩展(Object.preventExtensions)、密封(Object.seal)和冻结(Object.freeze)
1.扩展对象
Object.preventExtensions
Object.isExtensible
2.密封对象
Object.seal
Object.isSealed
3.冻结对象
Object.freeze
Object.isFrozen
1.Object.preventExtensions
阻止对象扩展,让一个对象变的不可扩展,也就是永远不能再添加新的属性
ES3 是没有办法阻止对象扩展的,定义对象后可以给对象添加任意属性
var obj = {name: 'John'}
// 又添加一个属性 age
obj.age = 30
// 又添加一个方法
obj.setAge = function(a) {
this.age = a
}
ES5 的 Object.preventExtensions 则可以阻止给对象添加新属性
var obj = {name: 'John'}
// 阻止对象扩展
Object.preventExtensions(obj)
// 添加新属性
obj.age = 30
// 测试新属性,是 undefined,表明未添加成功
console.log(obj.age)
- Object.isExtensible
判断一个对象是否可扩展,即是否可以给它添加新属性
//默认普通对象都是可以扩展的,这和 ES3 保持一致
var obj = {}
// true,表示可扩展
Object.isExtensible(obj)
//但调用 ES5 的 Object.preventExtensions 后就返回 false 了
var obj = {}
Object.preventExtensions(obj)
// false,表示不可添加新属性
Object.isExtensible(obj)
1.Object.seal
让一个对象密封,并返回被密封后的对象。密封对象是指那些不能添加新的属性,不能删除已有属性,以及不能修改已有属性的可枚举性、可配置性、可写性,但可以修改已有属性的值的对象。
//1.添加新属性
var obj = {name: 'John'}
// 密封
Object.seal(obj)
// 不能添加新属性
obj.age = 30
console.log(obj.age) // undefined
//2.删除已有属性
var obj = {name: 'John'}
// 密封
Object.seal(obj)
// 不能删除已有属性
delete obj.name // false
console.log(obj.name) // 'John',依然存在
//3.修改已有属性的可枚举性、可配置性、可写性
var obj = {name: 'John'}
// 密封
Object.seal(obj)
// 修改已有的配置属性
Object.defineProperty(obj, 'name', {
configurable: true,
writable: true,
enumerable: true
})
//4.修改已有属性的可枚举性、可配置性、可写性
var obj = {name: 'John'}
// 密封
Object.seal(obj)
// 修改已有的配置属性
Object.defineProperty(obj, 'name', {
configurable: true,
writable: true,
enumerable: true
})
//5.修改已有属性的值
var obj = {name: 'John'}
// 密封
Object.seal(obj)
// 可以修改已有属性的值
obj.name = 'Backus'
console.log(obj.name) // 'Backus'
2.Object.isSealed
判断一个对象是否是密封的(sealed)
var obj = {}
Object.isSealed(obj) // false
调用 Object.seal 的对象是密封的
var obj = {}
Object.seal(obj)
Object.isSealed(obj) // true
1.Object.freeze
这个方法比 Object.seal 更绝,冻结对象是指那些不能添加新的属性,不能修改已有属性的值,不能删除已有属性,以及不能修改已有属性的可枚举性、可配置性、可写性的对象。也就是说,这个对象永远是不可变的。
2.Object.isFrozen
判断一个对象是否被冻结(frozen)
普通对象是非冻结的,和 ES3 保持一致
var obj = {name: 'John'}
Object.isFrozen(obj) // false
调用 Object.freeze 的对象是冻结的
var obj = {name: 'John'}
Object.freeze(obj)
Object.isFrozen(obj) // true
参考文章:https://www.cnblogs.com/snandy/p/5278474.html
3.立即执行函数(IIFE)
IIFE: Immediately Invoked Function Expression,声明函数的同时立即调用这个函数。
为什么需要IIFE:
实际上,IIFE的出现是为了弥补JS在scope方面的缺陷:JS只有全局作用域(global scope)、函数作用域(function scope),从ES6开始才有块级作用域(block scope)。那么如何实现作用域的隔离呢?在JS中,只有function才能实现作用域隔离,因此如果要将一段代码中的变量、函数等的定义隔离出来,只能将这段代码封装到一个函数中。在JS中,当然声明函数的目的在大多数情况下也是为了复用,但是JS迫于作用域控制手段的贫乏,我们也经常看到只使用一次的函数:这通常的目的是为了隔离作用域了!既然只使用一次,那么立即执行好了!既然只使用一次,函数的名字也省掉了!这就是IIFE的由来。(隔离作用域,生成私有变量)
IIFE的常见形式:
(function foo(){
var a = 10;
console.log(a);
})();
(functionfoo(){
vara=10;
console.log(a);
}());
参考文章:http://softlab.sdut.edu.cn/blog/subaochen/2016/02/说一说js的iife/
for(var i = 0;i < 10; i++){
console.log(i);
}
//控制台输出
0
1
2
3
4
5
6
7
8
9
//此时全局i值是多少呢?也就是最后的i值
i
10
for(var i = 0;i < 10; i++){
console.log(i);
setTimeout(function(){
console.log(`i:${i}`)
},1000)
}
//输出结果(因为1s之后执行,全局i已经是10了)
i:10
4.Temporal Dead Zone(TDZ)暂时性死区
console.log(color);
let color = 'yellow';
还没有评论,来说两句吧...