屏蔽属性
在寫之前,先看一段代碼:
function Foo(){} Foo.prototype.a=4; var instance=new Foo(); instance.a='lala';大家猜,Foo.prototype對象上的a屬性的值會不會被修改?我們可以來測試一下:
function Foo(){} Foo.prototype.a=4; var instance=new Foo(); instance.a='lala'; console.log(Foo.prototype.a); // 4 console.log(instance.a); // lala顯然答案是不會。實際上,會在實例instance本身創建一個同名的a屬性:
function Foo(){} Foo.prototype.a=4; var instance=new Foo(); instance.a='lala'; console.log(instance.hasOwnProperty('a')); // true這就是我們所說的“屏蔽屬性”,當要輸出instance.a的值時,按照原型鏈的查找規則,首先會在instance本身查找有沒有a屬性,沒有的話會沿它的原型對象找,直到找到就停止查找,所以,這個例子要輸出instance.a則會輸出lala,而不會輸出4,相當于屏蔽了原型對象上的同名屬性。
但是會為instance添加a屬性是有條件的,條件就是原型對象上的同名屬性是可寫的(writable:true),如果不可寫(writable:false),則既不會修改原型上的a屬性也不會為instance創建一個a屬性:
function Foo(){} Foo.prototype.a=4; Object.defineProperty(Foo.prototype,'a',{ writable:false // 不可寫 }); var instance=new Foo(); instance.a='lala'; console.log(instance.hasOwnProperty('a')); // false console.log(Foo.prototype.a); // 4另一種情況是,如果原型對象上的同名屬性是一個具有setter方法的屬性,則執行instance.a='lala';調用的是setter方法而不是為instance添加a屬性:
function Foo(){} Foo.prototype.a=4; Object.defineProperty(Foo.prototype,'a',{set:function(){console.log('lala');} }); var instance=new Foo(); instance.a=100; // lala console.log(instance.hasOwnProperty('a')); // false console.log(Foo.prototype.a); // undefined注意,setter方法是由instance對象調用的(注意this):
function Foo(){} Object.defineProperty(Foo.prototype,'a',{set:function(){this.age=20;} }); var instance=new Foo(); instance.a=100; console.log(instance.hasOwnProperty('age')); // true console.log(instance.a); // 20你看,instance本身就有了age屬性,也就是說,如果利用setter定義任何屬性,這個操作只針對instance本身。
?
轉載于:https://www.cnblogs.com/linweinb/p/8597051.html
總結
- 上一篇: Struts2框架原理
- 下一篇: Zygote和System进程的启动过程