JavaScript原型與原型鏈分析
JavaScript沒有類的概念,但幾乎所有的東西又是基於物件的,同時也能實現繼承,這就是js跟其他OOP語言最大的不同之處,這也是js最難理解的一塊。下面我來說說我個人的理解。
首先從建立物件說起,一般會有下面幾種方法:
1.建立一個Object例項,然後給它新增屬性和方法。
var person() = new Object(); person.name = 'mikej'; person.sayName = function(){ alert(this.name); }
2.也可以這樣寫:
var parson = { name : 'mikej', sayName : function(){ alert(this.name); } }
3.這兩種建立物件的方法很簡單,但都有缺陷,使用同一個模式建立物件的時候,會產生大量重複程式碼。於是就有了工廠模式:
function createPerson(name){ var p = new Object(); p.name=name; p.sayName = function(){ alert(this.name); }; return p; } var p1 = createPerson('mikej'); var p2 = createPerson('tom');
這樣就可以無限建立物件了。
4.還有一種方法,跟工廠模式異曲同工,叫做建構函式模式:
function Person(name){ this.name=name this.sayName = function(){ alert(this.name); } this.say = function(){ alert('hi'); } } var p1 = new Person('mikej'); var p2 = new Person('tom');
這裡有幾個值得關注的地方:沒有顯示的建立物件、函式名Person使用的是大寫字母P(這是必須的)、p1和p2中都有一個constructor(建構函式)屬性,指向Person。同時p1和p2既是Object的例項,也是Person的例項。
alert(p1.constructor == Person); //true alert(p1 instanceof Object); //true alert(p1 instanceof Person); //true
//5.11更新:以一個phper的角度看的話,之前很容易將建立物件的流程想成這樣,Person就是一個“類”,然後用new Person('mikej')
例項化了這個類,並且傳入引數。但實際上並不是這樣的,建立的流程應該是這樣:首先,建立一個空物件,然後用apply方法,第一個引數是這個空物件,第二個引數是上下文的引數,這樣Person中的this就會指向這個物件,也就是p1。
var p1 = new Person('mikej'); //上面程式碼就相當於 var p1 = {}; Person.apply(p1, ['mikej']);
建構函式模式看上去很好,但是它有一個弊端就是浪費記憶體,接上例
alert(p1.say == p2.say) //false
.為了避免這個缺陷,可是使用原型模式來建立物件,js中的每個物件都有一個prototype屬性用來指向另外一個物件,這個物件的所有屬性和方法都會被建構函式的例項繼承,是共享的,這就意味著,我們可以把那些不變的屬性和方法,定義到prototype物件上。
function Person(name){ this.name = name; } //Person的原型物件 Person.prototype = { say: function(){ alert('hi'); }, sayName: function(){ alert(this.name); } }; var p1 = new Person("mikej"); var p2 = new Person("tom"); p1.sayName(); p2.sayName(); //下面就可以看出方法實現了共享 alert(P1.say == P2.say) //true alert(P1.sayName == P2.sayName) //true
再來擴充套件一下上面的例子,使用原型來實現繼承。
function Person(name){ this.name = name; } Person.prototype = { say: function(){ alert('hi'); }, sayName: function(){ alert(this.name); } }; function Programmer(){ this.say = function(){ alert('im Programmer, my name is ' + this.name); } } Programmer.prototype = new Person('mikej'); //手動修正建構函式 Programmer.prototype.constructor = Programmer; var p1 = new Programmer(); console.dir(Programmer.prototype.constructor);//Programmer console.dir(p1.constructor);//Programmer console.dir(p1);
Programmer的原型指向了Person的一個例項,那麼所有的Programmer的例項都能繼承Person和Person的原型了。
這裡會有一個問題。
預設原型物件裡有一個constructor屬性,指向它的建構函式。而每一個例項也有一個constructor屬性,會預設呼叫prototype物件的constructor屬性。
假設沒有Programmer.prototype = new Person('mikej');
Programmer.prototype.constructor是指向Programmer的。p1的構造也指向Programmer
alert(Programmer.prototype.constructor == Programmer) //true alert(p1.constructor == Programmer) //true
但有了這句Programmer.prototype = new Person('mikej');
之後,
Programmer.prototype.constructor就指向了Object,也就是Person.prototype指向的物件的構造。p1.constructor也指向了Object。但p1明明是建構函式Programmer生成的,這就造成了繼承的混亂,所以我們必須手動修正建構函式,也就是下面這程式碼。
Programmer.prototype.constructor = Programmer;
好了,現在我們再來看看原型鏈:
console.dir(p1);
這句程式碼的結果是
可以看出,p1是Programmer的例項,Programmer的原型是Person,Person的原型是Object,再網上就是JS的物件了。這就是原型鏈,也就是說,JavaScript的繼承是基於原型鏈來實現的。
相關文章
- JavaScript原型與原型鏈JavaScript原型
- JavaScript 原型 與 原型鏈JavaScript原型
- javascript——原型與原型鏈JavaScript原型
- javascript之原型與原型鏈JavaScript原型
- JavaScript中原型與原型鏈JavaScript原型
- 7. JavaScript 原型與原型鏈JavaScript原型
- JavaScript系列之原型與原型鏈JavaScript原型
- 再解 JavaScript 原型與原型鏈JavaScript原型
- 深入JavaScript系列(六):原型與原型鏈JavaScript原型
- JavaScript 原型及原型鏈JavaScript原型
- 原型與原型鏈原型
- 三分鐘看完JavaScript原型與原型鏈JavaScript原型
- 三張圖搞懂JavaScript的原型物件與原型鏈JavaScript原型物件
- JavaScript中的原型、原型鏈、原型模式JavaScript原型模式
- javascript - 繼承與原型鏈JavaScript繼承原型
- JavaScript 原型鏈JavaScript原型
- JavaScript原型鏈JavaScript原型
- 原型物件與原型鏈原型物件
- JS 原型與原型鏈JS原型
- JS原型與原型鏈JS原型
- javascript原型和原型鏈詳解JavaScript原型
- 淺談JavaScript原型及原型鏈JavaScript原型
- [JavaScript]原型、原型鏈、建構函式與繼承JavaScript原型函式繼承
- 如何理解JavaScript的原型和原型鏈?JavaScript原型
- JavaScript深入之從原型到原型鏈JavaScript原型
- JavaScript 深入之從原型到原型鏈JavaScript原型
- 徹底搞懂JavaScript原型和原型鏈JavaScript原型
- JavaScript之原型鏈JavaScript原型
- JS中的原型與原型鏈JS原型
- JS原型與原型鏈圖解JS原型圖解
- 從問題入手,深入瞭解JavaScript中原型與原型鏈JavaScript原型
- JavaScript教程全套影片合集:原型及原型鏈JavaScript原型
- 【機制】JavaScript的原型、原型鏈、繼承JavaScript原型繼承
- 《JavaScript 闖關記》之原型及原型鏈JavaScript原型
- javascript基礎-原型鏈與繼承JavaScript原型繼承
- 【Javascript 基礎】原型鏈JavaScript原型
- 深入理解JS原型與原型鏈JS原型
- 面試之JS篇 - 原型與原型鏈面試JS原型