js中的神奇方法Object.defineProperty
Dec 28, 2018 00:00 · 834 words · 2 minute read
一年多前开始接触前端,从用原生(html+js+css)的简单页面到使用框架(jquery, vue, angular, ionic)构建的稍微复杂的前端页面/app. 十分感慨前端技术的进步迅速, 今天要说的 Object.deineProperty 其实是ES5.1 就存在的一个js的方法, vue与angular利用它实现了数据与视图的变化绑定(MV)
认识 Object.deineProperty
语法
Object.defineProperty(obj, prop, descriptor)
参数:
obj
: 要在其上定义属性的对象prop
: 要定义或修改的属性的名称descriptor
: 将被定义或修改的属性描述符(可选参数)
descriptor的6个属性:
属性名 | 默认值 | 作用 |
---|---|---|
configurable |
false | 当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除 |
enumerable |
false | 是否能被 for in, Object.keys 枚举 |
value |
undefine | 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等 |
writable |
false | 当且仅当该属性的writable为true时,value才能被赋值运算符改变 |
get |
undefine | 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象) |
set |
undefine | 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值 |
阅读官方文档
例子
1.configurable
, enumerable
, value
, writable
的使用
/**
* 先看一个普通的对象定义
*/
var user = {name: 'Simeon'};
Object.getOwnPropertyDescriptor(user, 'name');
// {value: "Tom", writable: true, enumerable: true, configurable: true}
/**
* 使用 Object.defineProperty 方法定义
*/
var user = {};
Object.defineProperty(user, 'name', {
value: 'Simeon'
});
Object.getOwnPropertyDescriptor(user, 'name');
// {value: "Simeon", writable: false, enumerable: false, configurable: false} (注意属性的默认值)
console.log(user.name); // "Simeon"
user.name = 'nobody';
console.log(user.name); // "Simeon" 这是因为 "writable" 为false
console.log(Object.keys(user)); // "[]" 这是因为 "enumerable" 为false
Object.defineProperty(user, 'name', {
value: 'Simeon',
configurable: true,
enumerable: true,
writable: true,
}); // 报错: "Uncaught TypeError: Cannot redefine property: name" 这是因为 首次设置的"configurable"为 默认值 false
2.get
, set
的使用
var user = {};
Object.defineProperty(user, 'name', {
get: function() {
console.log('get');
return user._name;
},
set: function(value) {
console.log('set');
user._name = value;
}
})
console.log(user.name); // get\n undifined
user.name = 'Simeon'; // set
console.log(user.name); // get\n Simeon
上面的例子还有一种简便的写法
// 这种方式只能在声明时使用
var user = {
get name() {return this._name;},
set name(value) {this._name = value;}
};