一、数据劫持
- 数据劫持:能够拦截到数据被使用或被修改的时机,在这个时机除了可以获取数据的值或对数据的值进行修改之外,还可以执行其他功能。
- 当对数据进行修改时,除了要修改数据自身之外,还希望对所有使用了该数据的位置进行同步修改。
对象的访问器属性
- 访问器属性由 “getter” 和 “setter” 方法表示。在对象字面量中,它们用 get 和 set 表示:
let obj = {
_msg: "hello world",
get msg() {
return this._msg;
},
set msg(value) {
this._msg = value
}
};
- 当读取 obj.msg 时,getter 起作用,当 obj.msg 被赋值时,setter 起作用。
- 从外表看,访问器属性看起来就像一个普通属性。这就是访问器属性的设计思想。我们不以函数的方式调用,我们正常读取它,getter 会在幕后运行。
- 如果,访问器属性只有一个 getter。在赋值操作 obj.msg = xxx,将会出现错误:Error(属性只有一个 getter)
- 这样就会有一个“虚拟”的属性,它是可读且可写的。我们会利用这种方式进行数据劫持。
二、Object.defineProperty()
Object.defineProperty(对象, 属性名, { 配置项 })
- 配置项:
value
:该属性对应的值writable
:该属性是否可被重写,默认是 falseenumerable
:该属性是否可被枚举,默认是 falseget
:是一个函数, 叫做 getter 获取器,可以来决定该属性的值
- get 函数的返回值, 就是当前这个属性的值
- 注意: 不能和
value
和 writable
一起使用,会报错
set
:是一个函数,叫做 setter 设置器,当你需要修改该属性的值的时候,会触发该函数
Object.defineProperty(obj, 'age', {
enumerable: true,
get () {
return 20
},
set (val) {
console.log('你想修改 age 的值, 你想修改为 : ', val)
}
})
- 升级版:
Object.defineProperties(对象, { 配置项组 })
Object.defineProperties(obj, {
属性1: { 配置项 },
属性2: { 配置项 }
})
- 注意:
Object.defineProperty
和Object.defineProperties
无法劫持后来添加的属性
三、Proxy()
- ES6新增的本地对象,语法为:
new Proxy(原始对象, { 配置项 })
,用于实现数据代理。
const obj = { name: 'Jack', age: 18 }
const result = new Proxy(obj, {
get (target, property) {
return target[property];
},
set (target, property, val) {
target[property] = val
console.log('你试图修改 ' + property + ' 属性, 你想修改为 : ', val, ' 我需要根据你修改的内容重新渲染页面')
return true;
}
})
四、补充
1. Object类新增方法
Object.create(obj, { 配置项组 })
- 创建(返回)一个新对象,这个新对象的
__proto__
指向obj
- 配置项组,键为新对象的属性名,值为当前属性的配置项
- 配置项,参考
Object.defineProperty()
的配置项
Object.is(value1, value2)
Object.assign(obj1, obj2)
- 将
obj2
合并到obj1
,并返回合并之后的obj1
Object.keys(obj)
Object.values(obj)
- 返回对象所有可被枚举key的
value
,以数组的形式呈现
Object.setPrototypeOf(obj, prototype)
- 修改
obj
的__proto__
指向指定的prototype
,prototype
为对象
或null
,返回值为修改后的obj
Object.getPrototypeOf(obj)
2. Array类新增方法
Array.from( 参数 )
- 根据指定参数创建新数组,要求该参数可被迭代。
- 可根据伪数组创建真数组,实现伪转真
- 数组的深拷贝
Array.of( 数据, ... )
- 根据指定数据创建数组,类似
Array( 数据, ... )
,但Array.of( 数据, ... )
接收一个数值型数据时,不会作为长度
Array.isArray( 数据 )