高級javascript---原型和原型繼承

高級javascript---原型和原型繼承javascript

在 JavaScript 中,prototype 是函數的一個屬性,同時也是由構造函數建立的對象的一個屬性。 函數的原型爲對象。 它主要在函數用做構造函數時使用。java

function Vehicle(wheels, engine) {
    this.wheels = wheels;
    this.engine = engine;
}

在上面的示例中,Vehicle 函數的原型是使用 Vehicle 構造函數實例化的任何對象的原型。app

可使用 prototype 屬性向對象添加屬性和方法,甚至於已建立的對象也是如此:函數

var testVehicle = new Vehicle(2, false);
Vehicle.prototype.color = "red";
var testColor = testVehicle.color;

  

testColor 的值爲「red」。學習

你甚至能夠向預約義的對象添加屬性和方法。 例如,你能夠在 String 原型對象上定義一個 Trim 方法,腳本中的全部字符串都將繼承該方法。ui

String.prototype.trim = function()
{
    // Replace leading and trailing spaces with the empty string
    return this.replace(/(^\s*)|(\s*$)/g, "");
}
var s = "    leading and trailing spaces    ";
// Displays "    leading and trailing spaces     (35)"
window.alert(s + " (" + s.length + ")");
// Remove the leading and trailing spaces
s = s.trim();
// Displays "leading and trailing spaces (27)"
window.alert(s + " (" + s.length + ")");

使用原型經過 Object.create 從一個對象派生另外一個對象

prototype 對象可用於從一個對象派生另外一個對象。 例如,你可使用 Object.create 函數派生使用咱們以前定義的 Vehicle 對象的原型(以及所需的任何新屬性)的新對象Bicycle。this

var Bicycle = Object.create(Object.getPrototypeOf(Vehicle), {
    "pedals" :{value: true}
});

Bicycle 對象具備屬性 wheels、engine、color 和 pedals,而且其原型爲 Vehicle.prototype。 JavaScript 引擎會查找 Bicycle 的 pedals 屬性,並查看原型鏈以便查找Vehicle 的 wheels、engine 和 color。spa

Hh924508.collapse_all(zh-cn,VS.94).gif更改對象的原型

在 Internet Explorer 11 中,能夠經過 __proto 屬性用新原型替換對象或函數的內部原型。 使用此屬性時,將繼承新原型的屬性和方法以及其原型鏈中的其餘屬性和方法。prototype

如下示例演示如何更改對象的原型。 此示例演示當更改對象原型時,對象的繼承屬性將如何更改。code

 

function Friend() {
    this.demeanor = "happy";
}

function Foe() {
    this.demeanor = "suspicious";
}

var friend = new Friend();
var foe = new Foe();

var player = new Object();
player.__proto__ = foe;

friend.ally = "Tom";

if (console && console.log) {
    console.log(player.demeanor === "happy" );      // Returns false
    console.log(player.demeanor === "suspicious");  // Returns true
    console.log(player.ally === "Tom");             // Returns false
    // Turn the foe to a friend.
    player.__proto__ = friend;
    console.log(player.demeanor === "happy");       // Returns true
    console.log(player.demeanor === "suspicious");  // Returns false
    console.log(player.ally === "Tom");             // Returns true
}

上面是摘自http://msdn.microsoft.com/zh-cn/library/hh924508(v=vs.94).aspx上的原文。

下面是我從慕客網上看到的一個問題,仔細分析以後感受挺有意思,因而記下錄來。

仔細分析 Man.prototype = new People 與 Man.prototype = People.prototype 這兩種繼承的區別

function People (){
        this.name = 'frog';
        this.age = 29;
    }
    
    People.prototype.getName = function(){
        return this.name;
    }
    
    function Man(){
       this.name = 'rat';
       this.age = 3;
    }
    
    Man.prototype = People.prototype;

    //某一天,新來的小夥伴修改了這個方法
    Man.prototype.getName = function(){
        return this.age;
    }
    
    var p = new People;
    var n = p.getName();
    console.log(n); // 輸出29而不是 frog 
    //說明直接用原開鏈,父類會被子類影響

 因此通常不直接用對象原型,而是用對象的實例
function People (){
        this.name = 'frog';
        this.age = 29;
    }
    
    People.prototype.getName = function(){
        return this.name;
    }
    
    function Man(){
       this.name = 'rat';
       this.age = 3;
    }
    
    Man.prototype = new People;

    //再次修改原型上的方法
    Man.prototype.getName = function(){
        return this.age;
    }
    
    var p = new People;
    var n = p.getName();
    console.log(n);  // frog 說明父類沒有受影響

這樣改,子類的修改就不會影響到父類了,不過這樣作有一個缺點,一是每次實例化Man的時候都會new People, 二是People上的屬性也會繼承到Man上來,一般咱們只想要繼承父對象上的方法,不須要它的屬性,因此,就出現了下面的用法

f = function(){};
f.prototype = People.prototype;
Man.prototyep = new f();
經過這樣中轉一下,就能夠只繼承People上的方法,而不承它的屬性,同時子類的修改,不會影響到父類了。若是您以爲這文章對您有幫助,請點擊【推薦一下】,想跟我一塊兒學習嗎?那就【關注】我吧!
相關文章
相關標籤/搜索