javascript--prototype


每個javascript函數自動prototype屬性,使用prototype可以為類聲明通用的屬性,當一個對象被創建時,構造函數將會把它的屬性的prototype賦給對象的內部屬性__proto__

另外,javascript使用prototype實現繼承機制

創建通用屬性


 

不采用原型時:

function Fish(name, color){
    this.name = name;
    this.color = color;
    this.livePlace = "water";
    this.canSwim = function(){ console.log("I can swim");};
}

var cod = new Fish("cod","white");
var salmon = new Fish("salmon","black");

console.log(cod.livePlace);   //water
console.log(salmon.livePlace); //water
console.log(salmon.canSwim == cod.canSwim); //false

 

此時每申明一個實例Fish,都會有相同的屬性值livePlace,有些重復,無法共享方法和屬性

 

使用prototype,實例可以共享屬性

function Fish(name, color){
    this.name = name;
    this.color = color;
}
 Fish.prototype.livePlace = "water";
 Fish.prototype.canSwim = function(){ console.log("I can swim");};

var cod = new Fish("cod","white");
var salmon = new Fish("salmon","black");

console.log(cod.livePlace);
console.log(salmon.livePlace);
console.log(salmon.canSwim == cod.canSwim); //true

例子中 實例共享屬性livePlace和canSwim屬性

 

 

 prototype 與 __proto__


 

1.所有函數的__proto__都指向Function.prototype

2. 對象的__proto__指向 其構造器的prototype

 

eg:

function Fish(name, color){
    this.name = name;
    this.color = color;
}
 Fish.prototype.livePlace = "water";
 Fish.prototype.canSwim = function(){ console.log("I can swim");};

var cod = new Fish("cod","white");
var salmon = new Fish("salmon","black");
var object = {};
 console.log(Fish.__proto__ === Function.prototype); //true
console.log(cod.__proto__ === Fish.prototype);      //true
console.log(object.__proto__ === Object.prototype); //true
console.log(Object.getPrototypeOf(Fish) === Fish.__proto__); //true



注意: 瀏覽器不支持getPrototypeOf時可以使用Object.getPrototypeOf 替代

 

屬性相關方法


 

hasOwnProperty() :是否含有某屬性

isPrototypeOf() : 是否是..的原型

in 

 

 eg:

function Fish(name, color){
    this.name = name;
    this.color = color;
}
 Fish.prototype.livePlace = "water";
 Fish.prototype.canSwim = function(){ console.log("I can swim");};

var cod = new Fish("cod","white");
var salmon = new Fish("salmon","black");


console.log(Fish.prototype.isPrototypeOf(salmon)); //true
console.log(cod.hasOwnProperty("name")); //true
console.log("livePlace" in cod);  //true

 

 使用prototype實現繼承


 方式一:

 

//父類

function People(name,age){
    this.name = name;
    this.age = age;
    this.species = "human";
    this.getName = function(){
        return this.name;
    }
    this.getAge = function(){
        return this.age;
    }
    this.sayHello = function(){
        console.log("hi,I am the father class");
    }
}

//子類
function Children(name, age){
    this.name = name;
    this.age = age;
}

Children.prototype = new People();
console.log(Children.prototype.constructor === People); //true
Children.prototype.constructor = Children;

var wish = new Children("wish");
console.log("the name of wish is:"+wish.getName());  //the name of wish is:wish 
console.log(wish.sayHello());  //hi,I am the father class 

 

 

注意:

1. prototype對象包含一個contructor屬性,每一個實例也有一個constructor屬性,默認調用prototype對象的constructor屬性。Children.prototype = new People();給prototype賦了新的值, 此時Children.prototype.constructor值變為People,因而我們需要修改以保證原型鏈的正確性

2. 只要修改了prototype,一定要將新的prototype的constructor指向原來的構造函數

相關信息查看js類型判斷及鴨式辨型

 

 方式二:

Children.prototype = People.prototype;

Children.prototype.constructor = Children;

注意:此種方式下如果 Children.prototype做了更改時,People.prototype也會相應更改

 

可以使用空函數作為中間介,以改善上面兩種方式,如下:

Var F = function(){}
F.prototype = People.prototype;
Children.prototype = new F();
Children.prototype.constructor = Children;

 

 


免責聲明!

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



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