prototype是顯示修改對象的原型的屬性。
這兩句很重要,以下我會詳細說明,此文章就是爲了說明上面的兩句話的含義。
- var Programmer = function(){};
- Programmer.prototype.WriteCode = function() {
- return "programmer writes code";
- };
- Programmer.prototype.Salary = 50000;
- var p = new Programmer();
我們來看一下p, p是一個引用指向programmer對象。我們給programmer對象的prototype定義了一個屬性Salary和一個方法WriteCode();
顯然我們直接定義了Programmer.prototype屬性和方法。
當我們執行p.Salary的時候,會先從p的this範圍內查找,沒有找到這時候會沿着原型鏈向上追溯,可是具體怎麼向上的呢,那麼就是使用了programmer.__proto__來找到programmer的prototype。我再強調一遍__proto__是JS內部自己用來追溯用的,雖然FF把它的給暴露出來了,但是我們不能依賴於這個,瀏覽器各自的實現不一樣,可見性不一樣,甚至變量名稱都不一樣。
這樣我們就很清楚了,我們使用prototype修改我們自定義類的原型的屬性和方法。
JS內部使用__proto__來追溯自己的原型。
再來看一個例子:
- var Person = function(){};
- Person.prototype.ask = function(){
- return "haha............";
- }
- Person.prototype.Say = function() {
- return "Person say";
- }
- Person.prototype.Salary = 50000;
- var Programmer = function(){};
- Programmer.prototype.WriteCode = function() {
- return "programmer writes code";
- };
- Programmer.prototype.Salary = 500;
- Programmer.prototype = new Person();
- var p = new Programmer();
執行p.WriteCode(), 會是什麼結果? //programmer writes code
NO, 應該是" ... has no method 'WriteCode' "
雖然我們定義了programmer.prototype.WriteCode, 但是在15行我們將programmer.prototype 設置爲 Person了。person及它的prototype都沒有WriteCode方法,所以“has no method 'WriteCode' ”。
使用這種方式便實現了JS的繼承。
第二個例子是一種錯誤的用法,希望引起大家的注意。