参照MDN:Object.defineProperty()是在一个对象上定义一个新属性,或者修改对象现有的属性并返回此对象的方法,也相当于在对象身上定义了一个拦截器。
关于更多Object.defineProperty()的更多用法,可以直接查看这一部分的文档Object.defineProperty()。
以下就Object.defineProperty()的实际运用做一些简单分析。
题目一:
/**
* 定义a,使打印出 “YOU WIN!”
*/
if(a==1 && a==2 && a==3){
console.log("YOU WIN!");
}
分析:
- 每次访问a的值的时候,a的值是在改变的,所以应当在访问a的值的时候就去改变a的值;
- a的值是定义在整个window上的;
- 所以利用Object.defineProperty()中的get()存取描述符可以实现对window.a属性的重写。
代码实现:
var _default = 0; //定义一个默认值
Object.defineProperty(window, 'a', {
get(){
return ++_default; //在访问a的时候,每次都进行+1的操作
}
});
if(a==1 && a==2 && a==3){
console.log("YOU WIN!"); //最终会输出YOU WIN!
}
题目二:
/**
* 题目描述,定义a值
* a = "Object";
* console.log(a); --> 输出{type:'Object', length: 6}
* a = "Array";
* console.log(a); --> 输出{type:'Array', length:5 }
* a = 123;
* console.log(a); --> 输出TypeError:The type is invalid
*/
分析:
- 此题目相当于对a的值进行重新访问,对于不同的a的输入进行重新赋值再访问;
- 所以这里应该用到存取描述符set。
代码实现:
var _default = undefined;
Object.defineProperty(window, "a", {
get(){
return _default;
},
set(newVal) {
switch(newVal){ //判断值
case "Object":
case "Array":
_default = {
type: newVal,
length: newVal.length,
}
break;
default:
throw new TypeError("The type is invalid");
}
}
})
a = "Object";
console.log(a); // {type: "Object", length: 6}
a = "Array";
console.log(a); // {type: "Array", length: 5}
a = 123;
console.log(a); // Uncaught TypeError: The type is invalid
题目三:
/**
* 题目描述:定义‘_’
* 使console.log(_+_+_+_+...)的值为abcd...
* 例如:
* _+_+_: abc
* _+_+_+_+_: abcde
*/
分析:
- 定义_,再根据26个字母的ASCII码进行转换
代码实现:
Object.defineProperty(window,"_", {
get(){
this._c = this._c || "a".charCodeAt(0);
var ch = String.fromCharCode(this._c);
if(this._c >='a'.charCodeAt(0) + 26) return; //大于26个字母之外的不作计算
this._c ++;
return ch;
}
})
console.log(_+_+_+_+_+_); // abcdef
以上主要使包含了Object.defineProperty()的set,get的简单运用,其实,Object.defineProperty()还enumerable,value,writable,configurable等描述符的使用,可查阅MDN。