javascript中原型(prototype)與原型鏈

javascript是一門動態語言(動態語言Dynamic Programming Language:動態類型語言,意思就是類型的檢查是在運行時作的,也就是常說的「弱類型」語言),沒有類的概念,有class保留字,但不能用做變量名javascript

原型:Javascript中的每個對象都有一個內部私有的鏈接指向另外一個對象,這個對象就是原對象的原型  注意:原型是一個對象,其餘對象能夠經過他實現屬性繼承java

原型鏈:這個原型對象也有本身的原型,直到對象的原型爲null爲止(也就是沒有原型),這種一級一級的鏈結構就稱爲原型鏈web

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

在這裏一旦當某個對象的原型所引用的對象的屬性被定義,就能夠被多個引用它的實例所繼承,即這些實例對象的原型所指向的就是這個原型對象。ide

 

基於原型鏈的繼承:wordpress

繼承屬性:函數

  javascript對象有兩種不一樣的屬性來源,一個是對象自身屬性,另外一是繼承於原型鏈上的屬性性能

例:ui

//假設有一個對象obj={a:1,b:2},而且obj所在的原型鏈以下:

//{a:1,b:2} ---> {b:3,c:4} ---> null

//a,b是obj自身的屬性

//本例中,用「對象.[[Prototype]]」來表示這個對象的原型

alert(obj.a);

//輸出1  證實a是obj自身的屬性

alert(obj.b);

//輸出2  證實b是obj自身的屬性

//在obj.[[Prototype]]中還有一個‘b’屬性,但它不會被訪問到。這種狀況稱爲「屬性遮蔽」。

alert(obj.c);

//輸出4  c不是obj自身的屬性,可是obj.[[prototype]]的屬性

alert(obj.d);

//輸出undefined  d既不是obj自身的屬性,也不是obj.[[prototype]]的屬性

//也不是obj.[[prototype]].[[prototype]](即null)的屬性,原型鏈已到頂端,沒有d屬性,返回undefined
View Code

繼承函數:this

  javascript中任何函數均可以添加到對象上做爲對象的屬性。繼承函數與繼承屬性基本沒差異,包括「屬性遮蔽」(至關於其餘語言中的方法重寫)  注意:當繼承的函數被調用時,this指向的是繼承的對象,而不是函數被聲明的原型對象

例:

var obj={

  a:2,

  m:function(b){

    return this.a+1;

  }

};

alert(obj.m());  //輸出3,當調用obj.m時,‘this’指向了obj

var p=Object.create(obj);  //p是一個對象,p.[[Prototype]]是obj

p.a=12;  //建立p的自身屬性a

alert(p.m());  //輸出13,當調用p.m時,‘this’指向了p,‘this.a’則是12
View Code


建立對象和生成原型鏈的不一樣方法:

使用普通方法建立對象:

例:

var obj={a:1};

//obj這個對象繼承了Object.prototype上面的全部屬性,因此可使用obj.hasOwnProperty('a')

//hasOwnProperty是Object.prototype的自身屬性,而Object.prototype的原型爲null,以下:

//obj ---> Object.prototype ---> null


var a=["one","two","three"];

//數組都繼承於Array.prototype,繼承者繼承其一些方法,如:indexOf,forEach,原型鏈以下:

//a ---> Array.prototype ---> Object.prototype --->null 


function F(){

  return 2;

}

//函數都繼承於Function.prototype,繼承者繼承其一些方法,如:call,bind,原型鏈以下:

//F ---> Function.prototype ---> Object.prototype --->null 
View Code

使用構造函數建立對象:

  javascript中,構造方法其實就是一個普通的函數。當時用new操做符來做用這個函數時,它就能夠被稱爲構造函數

例:

function Graph(){

  this.vertexes=[];

  this.edges=[];

}

Graph.prototype={

  addVertex:function(v){

    this.vertexes.push(v);

  }

};

var g=new Graph();

//g是生成的對象,他的自身屬性有‘vertexes’和‘edges’

//g被實例化時,g.[[Prototype]]指向了Graph.prototype
View Code

使用Object.create建立對象:
  ECMAScript 5 中引入了一個新的方法:Object.create 。能夠調用這個方法來建立一個新對象。新對象的原型就是調用create方法時傳入的第一個參數:

例:

var a={a:1};

//a ---> Object.prototype ---> null


var b=Object.create(a);

//b ---> a ---> Object.prototype ---> null

alert(b.a);

//輸出1 (繼承而來)


var c=Object.create(b);

//c ---> b ---> a ---> Object.prototype ---> null


var d=Object.create(null);

//d ---> null

alert(d.hasOwnProperty);

//輸出undefined,由於d沒有繼承Object.prototype
View Code

 

性能:

  在原型鏈上查找屬性比較耗時,對性能有反作用,這在性能要求苛刻的狀況下很重要。另外,試圖訪問不存在的屬性時會遍歷整個原型鏈。

  遍歷對象的屬性時,原型鏈上的每一個屬性都是可枚舉的。

  檢測對象的屬性是定義在自身上仍是在原型鏈上,有必要使用 hasOwnProperty 方法,該方法由全部對象繼承自 Object.proptotype

  hasOwnProperty 是 JavaScript 中惟一一個只涉及對象自身屬性而不會遍歷原型鏈的方法

 

相關文章:

  Angus Croll:JavaScript,JavaScript...

   @三月沙 :理解JavaScript原型

  

  Tranch(from MDN):繼承於原型鏈

更多知識分享:微笑空間站

相關文章
相關標籤/搜索