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)

2. 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';
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值