原型陷阱: 在處理原型問題上時,我們要註意兩種行為。 1. 當我們對原型對象執行完全替換的時候,有可能會觸發原型鏈的某種異常。 2. prototype.constructor 屬性是不可靠的。 下麵,我們新建一個構造函數,並創建兩個對象: 即使在對象she1和she2對象被創建之後,我們仍然可以對 ...
原型陷阱:
在處理原型問題上時,我們要註意兩種行為。
1. 當我們對原型對象執行完全替換的時候,有可能會觸發原型鏈的某種異常。
2. prototype.constructor 屬性是不可靠的。
下麵,我們新建一個構造函數,並創建兩個對象:
var her = fucntion(){ this.name = 'Anna'; } var she1 = her(); var she2 = her();
即使在對象she1和she2對象被創建之後,我們仍然可以對her()的原型添加屬性,並且之前創建的這些對象也可以訪問這些屬性。
her.prototype.say = function(){ return 'Hello' } she1.say(); // Hello she2.say(); // Hello
如果我們檢查一下這些對象的構造函數,會發現一切正常:
she1.constructor === her; // true she2.constructor === her; // true
現在,我們用一個新對象覆蓋掉該構造函數的原型對象:
her.prototype = { sex : 'women', height : '170cm' }
事實證明,原有對象不能訪問這些新增屬性了,但原有對象們與她們的構造函數還保持著一種神秘的聯繫:
she1.sex; // undefined
she1.say(); // Hello
而我們之後創建的對象使用的或訪問的都是更新過後的prototype對象。
var a = her(); a.say(); // a.say() is not defined; a.sex = 'women';
這時候,新對象的constructor就不會在指向her()了,而是指向Object().
a.constructor; // function Object(){}
she1.constructor; // function her(){this.name = 'Anna'}
當然我們可以設置constructor屬性的指向來解決上述異常:
function her(){}; her.prototype = {}; new her().constructor === her; // false her.prototype.constructor = her; new her().constructor === her; // true
當我們重寫prototype對象的時候,一定要重置prototype的constructor屬性。
就是辣麽酸爽