prototype為對象添加屬性和方法


可以通過prototype來為已經定義好的的"類"添加屬性和方法。這里來了解一下prototype的基礎知識。prototype是"構造函數"的屬性,不是實例的屬性.

示例:

function HiClass() {  
    this.sayHi = function(){  
        alert("hi");  
    }  
}  
  
var obj = new HiClass();   
alert(HiClass.prototype);//outputs [object, object]  
alert(obj.prototype);//outputs undefined  

 

在用prototype的方式實現繼承一個類的時候,要注意其可能覆蓋別的prototype方式添加的屬性和方法。如果HiClass.prototype.prop = 'value'是在HiClass.prototype = new HelloClass()之前則不會有prop屬性,如果在執行HiClass.prototype = new HelloClass()之后,HiClass的實例中會有prop屬性,這個應該很好理解。但是要注意代碼中不要不小心存在這樣的bug。

示例:

function HiClass() {  
    this.sayHi = function(){  
        alert("hi");  
    }  
}  
  
  
function HelloClass() {  
    this.sayHello = function(){  
        alert("hello");  
    }     
}  
//HiClass.prototype.prop = 'value';  //this.prop = function(){}寫法是可以繼承的,兩種寫法有區別滴
HiClass.prototype = new HelloClass();  
HiClass.prototype.prop = 'value';  
  
var obj = new HiClass();  
obj.sayHello();  
alert(obj.prop); 

 

在JavaScript中有一個prototype鏈,在對一個對象實例上調用方法或者獲取屬性的時候,先看實例對應的類有沒有對應的定義,沒有的話會沿着prototype鏈一直找,找不到則為undefined。如果某類都有

定義,則調用本身的定義。Object.prototype.foo = function(){}會對所有以定義的方法起作用,javascript中Object對象是所有對象的基類

示例:

function Object2() {  
        this.sayHi = function(){  
            alert("hi Object2");  
        }  
    }  
      
    function Object3() {  
        this.sayHi = function(){  
            alert("hi Object3");  
        }  
          
        this.sayHello = function(){  
            alert("hello Object3");  
        }  
          
    }  

Object2.prototype
= new Object3(); var obj = new Object2(); obj.sayHi(); //hi Object2 調用obj.sayHi();的時候,sayHi在Object2里已經定義,則調用本身的定義。 obj.sayHello(); //hi Object3 Object.prototype.foo = function(){ //會對所有以定義的方法起作用,javascript中Object對象是所有對象的基類 alert("f00 Object"); }; obj.foo(); //f00 Object Object2.foo(); //f00 Object Object3.foo(); //f00 Object a.foo(); //報錯

 

如果在實例里添加的屬性和方法與prototype里的屬性和方法重名,相對於實例和prototype都有這個屬性和方法,只是由於prototype鏈的訪問順序,先訪問到實例中的屬性和方法。如下面的例子說明了這一點

function Test(){};  
  
Test.prototype.prop1 = 'prop value';  
  
var obj = new Test();  //obj如果是一個方法又不一樣嘍;obj.prototype = new Test();不會繼承滴
  
obj.prop1 = 'instance value';  
  
alert(obj.prop1 );//outputs instance value  
  
alert(obj.hasOwnProperty("prop1"));//outputs true  
  
delete obj.prop1;alert(obj.prop1 ); //outputs prop value  由於prototype鏈的訪問順序,先訪問到實例中的屬性和方法,刪除的是第一個屬性
alert(obj.hasOwnProperty("prop1"));//outputs false  
alert("prop1" in obj);//outputs true  

delete Test.prototype.prop1;alert(obj.prop1 );//outputs undefined

 

再來看看一些構造函數和prototype的使用:

var myObj = {  
    prop1:'value1',  
    prop2:'value2'  
}  
  
Object.prototype.foo = function(){  
    alert("f00 Object");  
};  
  
//等價於  
//var myObj = new Object();  
//myObj.prop1 = 'value1';  
//myObj.prop2 = 'value2';  
  
alert(myObj.prop2);  //value2
myObj.foo();    // f00 Object

 

同時也可以如下的方式對prototype賦值,可以一次添加多個屬性和方法

function TestCls(){  
      
}  
TestCls.prototype = {  //可以一次添加多個屬性和方法
    prop1:'value1',  
    prop2:'value2'  
};  
myObj = new TestCls();  
alert(myObj.prop2);  //value2

 

上面的做法中有一個問題是改變prototype后,constructor也改變了。
所以要將prototype.constructor之前的值,比如第一個例子中要加上 HiClass.prototype.constructor=HiClass;constructor 屬性返回對創建此對象的數組函數的引用

//上面的做法中有一個問題是改變prototype后,constructor也改變了。  
//所以要將prototype.constructor之前的值,比如第一個例子中要加上 HiClass.prototype.constructor=HiClass  
function HiClass() {  
    this.sayHi = function(){  
        alert("hi");  
    }  
}  
  
  
function HelloClass() {  
    this.sayHello = function(){  
        alert("hello");  
    }     
}  
  
HiClass.prototype = new HelloClass();  
HiClass.prototype.constructor=HiClass  //constructor 屬性返回對創建此對象的數組函數的引用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM