ES6系列学习(1)

以你之姓@ 2022-02-14 00:45 313阅读 0赞

来源:
https://www.bilibili.com/video/av47304735/?p=1
https://www.youtube.com/watch?v=5s35h_6v4ZI&list=PLCRqr1mERvdJ0IZMD1U4oSB7k0gyAjyIx

1.var let const

const只是保证引用地址不变,所以变量里面内容可变。

  1. const person = {
  2. name : 'Jelly',
  3. age:20
  4. }
  5. //修改引用地址,会报错
  6. person = {name:'bool'}
  7. //修改对象里面属性,但是引用地址不变
  8. person.age = 21
  9. person
  10. {
  11. name:'Jelly',
  12. age:21
  13. }

2.我们延伸出:对象属性描述符、对象的扩展、密封和冻结。

对象属性描述符

对象是一个属性集合,对象的基本特征是属性名(name)和属性值(value)。ES5 增加了属性描述符,可以更细腻的控制属性的不同操作。属性描述符有 configurable、writable 和 enumerable。

属性描述符通常和 Object.defineProperty/Object.defineProperties 一起使用来定义属性,它也会受到诸如 Object.freeze/Object.seal 等方法改变。

1.configurable 当且仅当 configurable 为 true 时,该属性才能够被改变,也能够被删除(delete),默认为 false

  1. var obj = {}
  2. Object.defineProperty(obj, 'name', {
  3. value: 'John'
  4. })
  5. // 不能 delete
  6. delete obj.name // false
  7. Object.defineProperty(obj, 'name', {
  8. configurable: true,
  9. value: 'John'
  10. })
  11. // 可以delete
  12. delete obj.name // true

2.writable 当且仅当 writable 为 true 时,该属性才能被赋值运算符(=)改变,默认为 false

  1. var obj = {}
  2. Object.defineProperty(obj, 'name', {
  3. value: 'John'
  4. })
  5. obj.name = 'Backus' // 修改不起作用,仍然是 John,严格模式中会报错阻止修改
  6. Object.defineProperty(obj, 'name', {
  7. writable: true,
  8. value: 'John'
  9. })
  10. obj.name = 'Backus' // 被改为了 backus

3.enumerable 当且仅当 enumerable 为 true 时,该属性才能够出现在对象的枚举属性(for in)中,默认为 false

  1. var obj = {}
  2. Object.defineProperty(obj, 'name', {
  3. value: 'John'
  4. })
  5. // 不能遍历
  6. for (var a in obj) {
  7. console.log(a) // 无输出
  8. }
  9. Object.defineProperty(obj, 'name', {
  10. enumerable: true,
  11. value: 'John'
  12. })
  13. // 可以遍历
  14. for (var a in obj) {
  15. console.log(a) // 输出 "name"
  16. }

ES6 的 Object.keys 只返回 enumerable=true 的属性

  1. var obj = {name: 'John'}
  2. Object.defineProperty(obj, 'name', {
  3. value: 'Backus',
  4. enumerable: true
  5. })
  6. Object.defineProperty(obj, 'age', {
  7. value: 30,
  8. enumerable: false
  9. })
  10. Object.keys(obj) // ['name']

可以通过 propertyIsEnumerable 方法判断属性的 enumerable 值

  1. obj.propertyIsEnumerable('name') // true
  2. obj.propertyIsEnumerable('age') // false

4.使用 ES3(传统的) JSON 方式定义对象,其 configurable/writable/enumerable 默认都是 true,使用 ES5 的 Object.defineProperty/Object.defineProperties 方式定义对象,其 configurable/writable/enumerable 默认都是 false

  1. //ES3定义
  2. var obj = {name: 'John', age: 30}
  3. // configurable
  4. delete obj.name // true
  5. // writable
  6. obj.age = 32 // true
  7. // enumerable
  8. for (var a in obj) {
  9. console.log(a) // age
  10. }
  11. //ES5定义
  12. var obj = {}
  13. Object.defineProperty(obj, 'name', {
  14. value: 'John'
  15. })
  16. Object.defineProperty(obj, 'age', {
  17. value: 33
  18. })
  19. // configurable
  20. delete obj.name // false
  21. // writable
  22. obj.age = 32 // false
  23. // enumerable
  24. for (var a in obj) {
  25. console.log(a) // 无输出,不能遍历
  26. }

和属性描述符相关的几个函数

1.Object.defineProperty
2.Object.defineProperties
3.Object.getOwnPropertyDescriptor

  1. //Object.defineProperty
  2. var obj = {}
  3. Object.defineProperty(obj, 'name', {
  4. value: 'John'
  5. })
  6. Object.defineProperty(obj, 'age', {
  7. value: 33
  8. })
  9. //Object.defineProperties,Object.defineProperties 批量定制对象属性,内部其实循环方式调用 Object.defineProperty
  10. Object.defineProperties(obj, {
  11. name: {
  12. value: 'John',
  13. writable: true
  14. },
  15. age: {
  16. value: 30,
  17. enmuerable: true
  18. }
  19. })
  20. //Object.getOwnPropertyDescriptor 返回该对象某属性的描述器,描述器自身是一个对象
  21. var obj = {}
  22. Object.defineProperty(obj, 'name', {
  23. value: 'Backus',
  24. writable: true,
  25. enumerable: true
  26. })
  27. var des = Object.getOwnPropertyDescriptor(obj, 'name')
  28. 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 是没有办法阻止对象扩展的,定义对象后可以给对象添加任意属性

  1. var obj = {name: 'John'}
  2. // 又添加一个属性 age
  3. obj.age = 30
  4. // 又添加一个方法
  5. obj.setAge = function(a) {
  6. this.age = a
  7. }

ES5 的 Object.preventExtensions 则可以阻止给对象添加新属性

  1. var obj = {name: 'John'}
  2. // 阻止对象扩展
  3. Object.preventExtensions(obj)
  4. // 添加新属性
  5. obj.age = 30
  6. // 测试新属性,是 undefined,表明未添加成功
  7. console.log(obj.age)
  1. Object.isExtensible

判断一个对象是否可扩展,即是否可以给它添加新属性

  1. //默认普通对象都是可以扩展的,这和 ES3 保持一致
  2. var obj = {}
  3. // true,表示可扩展
  4. Object.isExtensible(obj)
  5. //但调用 ES5 的 Object.preventExtensions 后就返回 false 了
  6. var obj = {}
  7. Object.preventExtensions(obj)
  8. // false,表示不可添加新属性
  9. Object.isExtensible(obj)

1.Object.seal

让一个对象密封,并返回被密封后的对象。密封对象是指那些不能添加新的属性,不能删除已有属性,以及不能修改已有属性的可枚举性、可配置性、可写性,但可以修改已有属性的值的对象。

  1. //1.添加新属性
  2. var obj = {name: 'John'}
  3. // 密封
  4. Object.seal(obj)
  5. // 不能添加新属性
  6. obj.age = 30
  7. console.log(obj.age) // undefined
  8. //2.删除已有属性
  9. var obj = {name: 'John'}
  10. // 密封
  11. Object.seal(obj)
  12. // 不能删除已有属性
  13. delete obj.name // false
  14. console.log(obj.name) // 'John',依然存在
  15. //3.修改已有属性的可枚举性、可配置性、可写性
  16. var obj = {name: 'John'}
  17. // 密封
  18. Object.seal(obj)
  19. // 修改已有的配置属性
  20. Object.defineProperty(obj, 'name', {
  21. configurable: true,
  22. writable: true,
  23. enumerable: true
  24. })
  25. //4.修改已有属性的可枚举性、可配置性、可写性
  26. var obj = {name: 'John'}
  27. // 密封
  28. Object.seal(obj)
  29. // 修改已有的配置属性
  30. Object.defineProperty(obj, 'name', {
  31. configurable: true,
  32. writable: true,
  33. enumerable: true
  34. })
  35. //5.修改已有属性的值
  36. var obj = {name: 'John'}
  37. // 密封
  38. Object.seal(obj)
  39. // 可以修改已有属性的值
  40. obj.name = 'Backus'
  41. console.log(obj.name) // 'Backus'

2.Object.isSealed

判断一个对象是否是密封的(sealed)

  1. var obj = {}
  2. Object.isSealed(obj) // false

调用 Object.seal 的对象是密封的

  1. var obj = {}
  2. Object.seal(obj)
  3. Object.isSealed(obj) // true

1.Object.freeze

这个方法比 Object.seal 更绝,冻结对象是指那些不能添加新的属性,不能修改已有属性的值,不能删除已有属性,以及不能修改已有属性的可枚举性、可配置性、可写性的对象。也就是说,这个对象永远是不可变的。

2.Object.isFrozen

判断一个对象是否被冻结(frozen)

普通对象是非冻结的,和 ES3 保持一致

  1. var obj = {name: 'John'}
  2. Object.isFrozen(obj) // false

调用 Object.freeze 的对象是冻结的

  1. var obj = {name: 'John'}
  2. Object.freeze(obj)
  3. 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的常见形式:

  1. (function foo(){
  2. var a = 10;
  3. console.log(a);
  4. })();
  5. (functionfoo(){
  6. vara=10;
  7. console.log(a);
  8. }());

参考文章:http://softlab.sdut.edu.cn/blog/subaochen/2016/02/说一说js的iife/

  1. for(var i = 0;i < 10; i++){
  2. console.log(i);
  3. }
  4. //控制台输出
  5. 0
  6. 1
  7. 2
  8. 3
  9. 4
  10. 5
  11. 6
  12. 7
  13. 8
  14. 9
  15. //此时全局i值是多少呢?也就是最后的i值
  16. i
  17. 10
  18. for(var i = 0;i < 10; i++){
  19. console.log(i);
  20. setTimeout(function(){
  21. console.log(`i:${i}`)
  22. },1000)
  23. }
  24. //输出结果(因为1s之后执行,全局i已经是10了)
  25. i10

4.Temporal Dead Zone(TDZ)暂时性死区

  1. console.log(color);
  2. let color = 'yellow';

发表评论

表情:
评论列表 (有 0 条评论,313人围观)

还没有评论,来说两句吧...

相关阅读

    相关 es6学习

    1 基础知识补充 ESnext--下一代js语言 任何人都可以向标准委员会(TC39),要求更改语言标准 Stage 0    展示阶段 Stage 1 

    相关 自我学习es6(1)

            跟着网上的视频学习了下es6的一些新的语法,在这里做一个笔记记录下,也起到一个反思和加深记忆的作用。          我们之前用的js版本是ECMAScri