第一季:ES6
基础系列:html
思考题:前端
let , const , object.freeze()
的区别vue
从最简单的const
开始:git
按上面这样写 会报错程序员
提示:github
Assignment to constant variable.
vuex
赋值给了常量
数组
可是当咱们:bash
发现代码正常运行,没有报任何错前端框架
那么我再试一下对象
发现一切运行正常
接下来尝试let
:
发现代码运行正常无报错
咱们翻看阮一峰老师的ES6入门:
const:
let:
const
实际上保证的,并非变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。
对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,所以等同于常量。
但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即老是指向另外一个固定的地址),至于它指向的数据结构是否是可变的,就彻底不能控制了。
总结来讲:const 并不能真正意义上保证 ‘不变’
ES5的浅冻结,使用API Object.freeze()
正常状况下,下面这段代码:
最终输出:
{a: "a", b: {…}}
a的值是被改变了 但是打开注释的代码 Object.freeze(obj)
最终输出:
{a: 1, b: {…}}
此时a的值并无被改变,由于它被“冻结”了
上面有提到浅冻结,那么看看修改b的值会不会有效果:
最终输出以下:
{a: 1, b: {…}}
a: 1
b: {c: 2}
复制代码
证实b
也被冻结了
再次尝试修改C
的值:
输出:
{a: 1, b: {…}}
a: 1
b: {c: 2}
复制代码
看来Object.freeze()
也不能彻底冻结,可是万能的程序员小哥哥是不可能屈服的,简单粗暴的递归,深冻结 :
这时候咱们修改了c的值:
发现输出:
{a: 1, b: {…}}
a: 1
b: {c: 2}
复制代码
看来此次是真的冻住了,不过深冻结也要根据数据的类型判断进行冻结,不然就不能真正意义上的彻底冻结。
vue 1.0.18+
对Object.freeze()
提供了支持,对于data
或vuex
里使用freeze
冻结了的对象,vue
不会作getter
和setter
的转换。
若是你有一个巨大的数组或Object
,而且确信数据不会修改,使用Object.freeze()
可让性能大幅提高。
Object.freeze()
方法能够冻结一个对象。一个被冻结的对象不再能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。
但它冻结的是值,你仍然能够将变量的引用替换掉
上面提到的:
可枚举性、可配置性、可写性,以及不能修改已有属性的值
上面经过Object.defineProperty()
定义的属性,访问获得打印输出2
下面对三个属性描述符进行解析:
writable
:决定是否能够修改属性的值
打印输出仍是2
,属性a的值不能被改变
解析:writable:false
能够看做为属性不可改变,在严格模式("use strict";)下,引擎会抛出TypeError的异常,这表示咱们没法修改一个不可写的属性
configurable
:只要属性是可配置的,就可使用 defineProperty(...)
方法来修改属性描述符
注意⚠️
在false
状况下,若是修改,不论是不是严格模式,都会抛出TypeError
的错误
在这种状况下,咱们仍能够将可写性的状态由true
改成false
delete
属性也会被禁止(delete myObject.a;)
emumerable
:可枚举,若是将它设置为false,则这个属性将不会出如今枚举中,但能够正常访问他
属性描述符上面有介绍,最后介绍下访问描述符
定义对象时,加入访问描述符:
正常状况下,访问 p.age 输出18
可是设置p.age=101后:
就会抛出错误
index.html:65 Uncaught Error: invalid value
at Object.set age [as age] (index.html:65)
at index.html:71
复制代码
访问描述符的做用:
get : 每次获取属性时候调用 例如 console.log(p.age) 这时候会调用get
set : 每次设置属性的时候调用 例如 p.age = 101 他们两个甚至能够彻底无关
特别提示 ,它们两个的调用逻辑必定要捋清楚,耦合度过高容易进入死循环
著名的Vue框架在2.x版本就借此实现的响应式~
例如 :
只须要通知全部订阅这个数据改变的组件进行更新,而且传递新的值~
上面只是伪代码,可是大体思想如此
若是感受写得不错,欢迎点个在看,推荐到朋友圈
另外开源项目 Palantir
目前已经接入微前端,微前端框架正在编写中~
仓库地址:
https://github.com/JinJieTan/Palantir
复制代码
Palantir
仓库地址
欢迎加入~ 咱们的大群体,以及交流群,公众号回复:加群
便可加群