JavaScript原型prototype

1、JavaScript構造函數javascript

構造函數的寫法html

function Car(size,color){
    this.size = size;
    this.color = color;
    this.run = function(){
                   console.log("run");
               }
}

var Car = function(size,color){
    this.size = size;
    this.color = color;
    this.run = function(){
                   console.log("run");
               }
}

注:構造函數中定義的屬性,在該函數建立的對象中是不存在的。java

方法寫在構造函數的內部或外部函數

//函數內的方法
function Car(size,color){
    this.size = size;
    this.color = color;
    this.run = function(){
                   console.log("run");
               }
}


//prototype上的方法
function Car(size,color){
    this.size = size;
    this.color = color;
}

Car.prototype.run = function(){
    console.log("run");
}

//另外一種寫法
Car.prototype = {
    run: function(){
        console.log("run");
    }
}

prototype的使用ui

Car.prototype = {
    run: function(){
        console.log("run");
    }
}

//與上面直接使用對象字面量賦值不一樣,下面的方式使用函數表達式賦值
//這種方式的好處是能夠封裝私有的function,能夠達到public/private的效果
Car.prototype = function(){
    return {
        run: function(){console.log("run");}
    }
}
//問:若是不使用return返回一個對象,上面的方式會出錯嗎?

2、Function和Object對象this

建立函數的兩種方式prototype

var func = function(){}

var func = new Function(){}

//function關鍵字等價於new Function

使用typeof輸出一個對象的類型設計

alert(typeof(Function))); 
alert(typeof(new Function())); 
alert(typeof(Array)); 
alert(typeof(Object)); 
alert(typeof(new Array())); 
alert(typeof(new Date())); 
alert(typeof(new Object())); 

//前四條語句都會返回「function」,後三條返回「object」
//因而可知 new Function返回的仍是一個Function對象
//Object也是函數.由於Object的結構是function Object(){native code}.

3、prototype、__proto__、constructor指針

prototype是Function纔有的屬性,注意Function的實例也是Functioncode

__proto__是Object對象中的屬性,Firefox暴露出該屬性

constructor是Object對象中的屬性,指向構造函數。

4、定義函數、建立對象的過程

  • 定義一個函數F,JavaScript解釋器會爲該函數添加一個prototype屬性,並建立一個prototype對象,函數的prototype屬性的值是指向該prototype對象的引用;
  • prototype對象中添加一個constructor屬性,指向該函數;
  • 使用函數F建立對象,爲該對象添加一個__proto__屬性,指向F的prototype對象,該對象也具備constructor屬性,constuctor屬性能夠用來判斷對象的類型是否相同,可是constructor屬性是可變的,因此並不必定正確,instanceof操做符更可靠。
  • var Person = function () { };
    var p = new Person();
    
    //建立對象的過程以下
    
    var p={};
    p.__proto__=Person.prototype;
    Person.call(p);
    
    //使用call()函數是,this指針指向誰

     

5、原型鏈的頂端爲null

console.log(Object.prototype);//Object
console.log(Object.prototype.protoype);//undefined
console.log(Object.prototype.__proto__);//null
console.log(Function.prototype);//ƒ () { [native code] }
console.log(Function.prototype.protoype);//undefined
console.log(Function.prototype.__proto__);
/*{
constructor:ƒ Object()
hasOwnProperty:ƒ hasOwnProperty()
isPrototypeOf:ƒ isPrototypeOf()
propertyIsEnumerable:ƒ propertyIsEnumerable()
toLocaleString:ƒ toLocaleString()
toString:ƒ toString()
valueOf:ƒ valueOf()
__defineGetter__:ƒ __defineGetter__()
__defineSetter__:ƒ __defineSetter__()
__lookupGetter__:ƒ __lookupGetter__()
__lookupSetter__:ƒ __lookupSetter__()
get __proto__:ƒ __proto__()
set __proto__:ƒ __proto__()
}
*/

首先要明確一點,原型鏈是指對象的原型鏈,因此原型鏈上的全部節點都是對象,不能是字符串、數字、布爾值等原始類型。

另外,規範要求原型鏈必須是有限長度的(從任一節點出發,通過有限步驟後必須到達一個終點。顯然也不能有環。)

那麼,應該用什麼對象做爲終點呢?很顯然應該用一個特殊的對象。

好吧,Object.prototype確實是個特殊對象,咱們先假設用它作終點。那麼考慮一下,當你取它的原型時應該怎麼辦?即

Object.prototype.__proto__;

應該返回什麼?

取一個對象的屬性時,可能發生三種狀況:

  1. 若是屬性存在,那麼返回屬性的值。

  2. 若是屬性不存在,那麼返回undefined。

  3. 無論屬性存在仍是不存在,有可能拋異常。

咱們已經假設Object.prototype是終點了,因此看起來不能是狀況1。另外,拋出異常也不是好的設計,因此也不是狀況3。那麼狀況2呢,它不存在原型屬性,返回undefined怎麼樣?也很差,由於返回undefined一種解釋是原型不存在,可是也至關於原型就是undefined。這樣,在原型鏈上就會存在一個非對象的值。

因此,最佳選擇就是null。一方面,你無法訪問null的屬性,因此起到了終止原型鏈的做用;另外一方面,null在某種意義上也是一種對象,即空對象,由於null一開始就是爲表示一個「空」的對象存在的。這樣一來,就不會違反「原型鏈上只能有對象」的約定。

因此,「原型鏈的終點是null」雖然不是必須不可的,可是倒是最合理的。

---------------------------------------------

 

function 和prototype自己都含__proto__,其實自己也都是對象,本身繼承過來的,他們2個也是基本類型的實例。http://www.cnblogs.com/danghuijian/p/3755755.html

 

原生類型包括:number,string, bool, null, undefined;

非原生類型包括(對象類型):object, array, function

相關文章
相關標籤/搜索