天天看點

【web前端-了解js原型】了解Javascript中的原型對象、原型鍊和繼承

一、了解原型對象

當建立一個新函數時,系統會根據一組特定的規則為函數建立一個prototype屬性,該屬性會指向一個名為原型對象的對象,在預設情況下,該對象會自動生成一個構造函數(constructor),該構造函數是一個指向函數的指針。而在原型對象中,除了有這個構造函數,我們還可以添加其他的屬性和方法。

通俗來講就是,當我們建立一個函數A時,函數A内部會有一個屬性,該屬性指向一個對象(名字叫原型對象),而這個對象裡面預設有一個構造函數,這個構造函數指向我們最初建立的函數A。然後,我們還可以在原型對象中添加屬性和方法。

下面我們來看構造函數、構造函數的原型屬性和執行個體之間的關系:

構造函數内部會有一個prototype屬性,該屬性指向構造函數的原型對象,當通過構造函數建立執行個體時,該執行個體内部将包含一個指針,指向構造函數的原型屬性。該關系如圖所示

【web前端-了解js原型】了解Javascript中的原型對象、原型鍊和繼承

來看下面的例子:

//①預設情況下,構造函數是空的

function Person(){//構造函數首字母大寫

}

//②添加屬性和方法

Person.prototype.name="dp";
Person.prototype.doSomething=function(){
    alert(this.name);
};

//③定義好構造函數和其他屬性方法之後,就可以建立執行個體了

var person1=new Person();
var person2=new Person();
           

這兩個對象都是由A建立的,他們都可以調用A的原型中的屬性和方法

alert(person1.name);//dp
alert(person2.name);//dp
           

當然也可以将其重寫

person1="god";
alert(person1.name);//god
           

重寫後的屬性也可以删除

delete person1.name;
alert(person1.name);//dp
           

注意原型的動态性,如果你将①和②調換位置,如下:

function Person(){ }

var person3=new Person();

Person.prototype.name=”dp”;

然後你再執行alert(person3.name)會報錯,因為new完person3之後,相當于person3的構造函數和原型屬性都是預設值(空),而接下來的Person.prototype.name=”dp”相當于重寫了其原型對象,重寫原型對象的同時,割裂了原型對象和執行個體的關系,既然原型對象和執行個體沒有關系了,那麼person3.name就沒有意義,是以會報錯。

二、了解原型鍊

讓我們回顧一下構造函數、原型和執行個體的關系:構造函數内部會有原型對象,該原型對象中包含一個指向構造函數的指針,而執行個體包含一個指向原型對象的指針。

那麼,假如原型對象是另一個類型的執行個體呢?也就是說,原型對象包含一個内部指針,指向另一個類型的原型對象,相應的,該原型對象也包含一個指向其構造函數的指針,如圖所示。如果将這種關系延續下去,就形成了原型鍊。

【web前端-了解js原型】了解Javascript中的原型對象、原型鍊和繼承

實作原型鍊的基本模式如下:

<script type="text/javascript">
    function Animal(name) {
        this.name = name;//設定對象屬性
    }
    Animal.prototype.getName = function() {  
        alert("It is a "+this.name);
    }
    function Dog(name){
        this.name=name;
    }
    Dog.prototype=new Animal();//繼承了Animal
    Dog.prototype.getName=function(){
        alert("It is a "+this.name);
    };
    var tom = new Dog("dog");//建立Dog對象
    alert(tom.getName());//It is a dog
</script>
           

三、繼承

許多語言都支援兩種繼承方式:接口繼承和實作繼承。在ECMAscript中不支援接口繼承,隻支援實作繼承,而實作繼承主要是依靠原型鍊來實作。根據js語言的本身的特性,js實作繼承有五種方式,詳見部落格

繼續閱讀