nodejs中徹底沒有class的這個概念,這點跟PHP,JAVA等面向對象的語言很不同,沒有class跟object的區分,那麼nodejs是怎麼樣實現繼承的呢?node
對象是由屬性跟方法組成的一個東西,就像下面這樣:編程
var animal = { name: "animal", eat: function () { console.log('%s is eating', this.name); } }; animal.eat(); //animal is eating.
因爲nodejs中object徹底不和class關聯,咱們能夠自由的給對象添加屬性和方法:函數
animal.color = 'black'; animal.say = function () { console.log('I am color %s', this.color); } console.log(animal.color); //black animal.say(); //I am color black
繼承是面向對象中的重要概念,其實是把兩個對象創建關聯;nodejs中每一個對象都有一個__proto__屬性,要創建兩個對象之間的關聯就要用到這個屬性了:一個對象可使用__proto__關聯另一個對象(這個對象就是原型):this
var cat = { name: 'cat', __proto__: animal }; var dog = { name: 'dog', __proto__: animal }; cat.eat(); //cat is eating dog.eat(); //dog is eating
對象cat的原型是animal,對象dog的原型也是animal,而且它們兩個都沒有定義eat()方法,那是怎麼調用eat()方法的呢?prototype
答案是nodejs的機制,當cat對象調用eat方法時,cat對象會如今本身的方法中尋找eat方法,若是找不到,就會去原型的方法中尋找,若是原型中找不到,就會去原型的原型中去尋找...最後就會去Object那裏去找,若是還找不到,那就是這個方法未定義了。code
這樣,animal、cat、dog這三個對象經過__proto__創建起了一個原型鏈。在這裏,dog跟cat對象的name屬性覆蓋了animal的name屬性,還有this,在cat跟dog對象在調用eat方法時,分別指向了cat跟dog對象。對象
爲了讓nodejs內的對象能夠像面向對象編程那樣能夠new出一個對象實例,nodejs提供了一個叫作構造函數的東西:繼承
function Student(name) { this.name = name; this.sayHello = function () { console.log('Hello, my name is %s', this.name); } } var tom = new Student('Tom'); var mike = new Student('Mike'); tom.sayHello(); //Hello, my name is Tom mike.sayHello(); //Hello, my name is Mike
爲了讓代碼更規範,構造函數的名稱首字母要大寫。在這裏有沒有發現一個問題,傳統的面向對象編程中,方法都是定義在類中的,咱們這裏的代碼是定義在對象上的,這樣就意味着每個由構造函數new出來的對象都附帶一個sayHello的方法,這樣太浪費空間了。因而,nodejs就創造出了一種更高效的方法,將sayHello方法放到別的地方去。
還記得剛纔說的原型鏈嗎?當一個對象調用方法時,會順着原型鏈向上找,因此咱們能夠建立一個原型對象,將要調用的方法放到這個原型對象中,讓tom、mike這些從Student建立的對象指向這個原型就好了:內存
function Student(name) { this.name = name; } Student.prototype = { sayHello: function () { console.log('Hello, my name is %s', this.name); } } var tom = new Student('Tom'); var mike = new Student('Mike'); tom.sayHello(); //Hello, my name is Tom mike.sayHello(); //Hello, my name is Mike
每當new Student()時,確實會建立一個新的對象,而且把這個對象的原型__proto__指向Student.prototype這個對象,這樣一來就能找到sayHello()方法了,從而能減小內存消耗的實現了面向對象編程的繼承了。原型鏈