静态方法会直接在一个对象上定义一个新属性,或修改其现有属性,并返回此对象。
语法:Object.defineProperty(obj, prop, descriptor)
参数:
-
obj: 要定义属性的对象。
-
prop: 一个字符串或 Symbol,指定了要定义或修改的属性键。
-
descriptor: 要定义或修改的属性的描述符。
描述符:
-
数据描述符和访问器描述符可以包含以下可选键:
-
configurable:
-
当设置为 false 时
该属性的类型不能在数据属性和访问器属性之间更改
该属性不可被删除
其描述符的其他属性也不能被更改(但是,如果它是一个可写的数据描述符,则 value 可以被更改,writable 可以更改为 false)
-
-
enumerable:当前属性是否可被枚举
-
-
数据描述符还具有以下可选键:
-
value:与属性相关联的值。可以是任何有效的 JavaScript 值(数字、对象、函数等)。默认值为 undefined。
-
writable:如果与属性相关联的值可以使用赋值运算符更改,则为 true。默认值为 false。
-
-
访问器描述符还具有以下可选键:
-
get:
用作属性 getter 的函数,如果没有 getter 则为 undefined。当访问该属性时,将不带参地调用此函数,并将 this 设置为通过该属性访问的对象(因为可能存在继承关系,这可能不是定义该属性的对象)。返回值将被用作该属性的值。默认值为 undefined。
-
set:
用作属性 setter 的函数,如果没有 setter 则为 undefined。当该属性被赋值时,将调用此函数,并带有一个参数(要赋给该属性的值), 并将 this 设置为通过该属性分配的对象。默认值为undefined。
-
-
注意:如果描述符没有 value、writable、get 和 set 键中的任何一个,它将被视为数据描述符。如果描述符同时具有 [value 或 writable] 和 [get 或 set] 键,则会抛出异常。
返回值:传入函数的对象,其指定的属性已被添加或修改。
let obj = {}
Object.defineProperty(obj,'name',{
value:'Jack',
configurable: true,
writable: false,
enumerable: true,
})
let age = 18
Object.defineProperty(obj,'age',{
// value: 18, value与get冲突
// writable: true, writable与set冲突
configurable: false,
enumerable: true,
get: function(){
return age
},
set: function(value){
age = value
}
})
console.log(obj)
Vue2响应式原理
let obj = {
name: "freeman",
age: 18
}
function getResponObj(data){
let obj = {}
let keys = Object.keys(data)
for(let i=0;i<keys.length;i++){
Object.defineProperty(obj,keys[i],{
get(){
// 访问属性时,在此处收集视图依赖
return data[keys[i]]
},
set(value){
// 修改属性时,在此处去更新虚拟dom
data[keys[i]] = value
},
})
}
return obj
}
let newObj = getResponObj(obj)