Javascript原型學習筆記

三個基本概念:構造函數、原型、實例  

每個構造函數都有一個原型對象(prototype),原型對象都包含一個指向構造函數的指針(constructor),而實例都包含一個指向原型的內部指針(__proto__)。javascript

emp1:java

function Foo(y){ 
this.y = y ; 
}
Foo.prototype.x = 10;
Foo.prototype.calculate = function(z){ 
return this.x+this.y+z; 
};
var b = new Foo(20);
alert(b.calculate(30));

 全部函數的默認原型都是Object的實例,所以默認原型內部都有一個指針,指向Object.prototype,這也正是全部自定義對象都會繼承toString()、valueOf()等方法的根本緣由。chrome

Foo的構造函數時Function   任何一個對象的__proto__都有值,由於每個對象都有構造函數。函數

如圖:this

 

函數與對象

函數是對象,對象又都是經過函數建立的。任何一個函數內都有prototype屬性。spa

在javascript中,一個對象就是任何無序鍵值對的集合,若是它不是一個主數據類型(undefined,null,boolean,number,or string),那它就是一個對象。firefox

false明明是一個主數據類型,false.__proto__也會返回一個值 。由於在代碼執行它會被強制轉化成一個對象(Boolean 基本包裝類型)。prototype

原型寫法

分步寫法:(具備實時性)設計

function a (){
    this.age = 1;
}   
a.prototype.str = 'ss';
var b = new a();
a.prototype.name='tom';
console.log(b.str);//ss
console.log(b.name); //tom 

 

字面量寫法:(會致使原型重寫)    指針

        function a(){
            this.name = 'w';
        }
        a.prototype.str = 's';
        var b = new a();
        console.log(b.str); //s
       //字面量寫法
        a.prototype = {
            x:1
        };
        //a原型重寫並無反映到a以前建立 的實例中
        console.log(b.str); //s
        console.log(b.x);//undefined
        //a的原型反映到重寫後建立的實例中
        var c = new a();
        a.prototype.q = 3;
        console.log(c.x); //1
        console.log(c.q); //3
        console.log(c.str); //undefined

 

 

原型鏈 繼承

函數a的原型爲函數b的實例,函數a的實例就會繼承a和b的原型的全部方法和屬性。  見圖《JavaScript高級程序設計》p163

 

new

__proto__本質上實際上是標準裏規定的[[prototype]]屬性,本來是不可用 js 訪問的,後來(聽說標準裏又規定能夠)firefox 和 chrome 中把這個屬性命名爲__proto__。後來ES又添加了函數getPrototypeof,這樣就能夠經過這個函數來訪問這個屬性,因此這個__proto__如今不是標準的一部分。

而後,再說new的建立過程,當執行new func()的時候,執行過程以下:
一、首先建立一個新的對象,好比叫 obj
二、obj.[[prototype]] = func.prototype;
三、令this=obj,執行函數 func;
四、若是 func 的返回值是一個對象,則 new 的返回值就是這個對象,不然返回值是 obj

<script type="text/javascript">

var animal = function(){};
var dog = function(){};

animal.price = 2000;
dog.__proto__ = animal;
var tidy = new dog();

console.log(dog.price) //2000
console.log(tidy.price) // undefined

</script>

 

constructor

constructor指的就是對象的構造函數   對象是由函數構造的

function Foo(){}; 
var foo = new Foo(); 
alert(foo.constructor);//Foo 
alert(Foo.constructor);//Function 
alert(Object.constructor);//Function 
alert(Function.constructor);//Function 

由於Foo,Object,Function都是函數對象,又由於全部的函數對象都是Function這個函數對象構造出來,因此它們的constructor爲Function

 

prototype與constructor的關係 

function Dog(){}
(Dog === Dog.prototype.constructor);//true 
console.log(Dog.prototype.hasOwnProperty('constructor'));//true 

function Animal(){} 
function Person(){} 
var person = new Person(); 
console.log(person.constructor); //Person 

 

 任何一個函數的原型都有constructor屬性    

person是Person的實例,因此person繼承Person原型上的全部屬性和方法,Preson原型有constructor屬性並指向Preson,因此person有constructor屬性並指向Preson

深刻一點

function Animal(){} 
function Person(){} 
Person.prototype = new Animal(); 
var person = new Person(); 
alert(person.constructor); //Animal 

 

如圖

圖中的虛線表示Person默認的prototype指向(只做參考的做用)。可是咱們將Person.prototype指向了new Animal。

 

還有

hasOwnProperty instanceof isPrototypeOf函數 原型屬性值包含應用類型值等問題

相關文章
相關標籤/搜索