淺談JavaScript對象與繼承
來源:易賢網(wǎng) 閱讀:598 次 日期:2016-07-29 14:03:20
溫馨提示:易賢網(wǎng)小編為您整理了“淺談JavaScript對象與繼承”,方便廣大網(wǎng)友查閱!

JavaScript是我在C語言之后接觸的第二門編程語言,大一暑假的時候在圖書館找了一本中國人寫的JavaScript程序設(shè)計來看。那個時候在編程方面幾乎還是小白,再加上那本書根本沒有提JavaScript的編程機制,又有一些誤導(dǎo)性的話,一直以來對JavaScript有很深的誤解,認為JavaScript只是一門在瀏覽器上運行的面向?qū)ο笳Z言,值此文來寫下JavaScript當(dāng)中很具有迷惑性和容易誤解的地方。當(dāng)然限于作者水平有限,也沒有什么開發(fā)經(jīng)驗,所以難免有疏漏之處,還望批評指正。

JavaScript的對象

對象是什么

JavaScript代碼當(dāng)中隨處可見new關(guān)鍵字,很容易讓人產(chǎn)生誤解,認為JavaScript是Java一樣是基于類繼承的語言。但是事實并非如此,JavaScript當(dāng)中并沒有類,那JavaScript的對象不是類那又是什么呢?某種意義上說,JavaScript的對象就是Python當(dāng)中的字典(哈希表),其實也就是類似這樣的鍵值對:

me={

  "fisrtName" : "seek",

  "lastName" : "truth" ,

  "getName" : function(){

    return this.firstName+this.lastName; //this相當(dāng)于指向這個對象的指針

  }

}

這是一個比較有誤解性的地方,初次看到時候覺得有點無法理解,但仔細用一用還是覺得合理,我們既可以像Python一樣用[]運算符來獲取元素,也可以用.操作符來獲取元素:

me.firstName // => seek

me["lastName"] //=> truth

me.getName() // => seektruth

new運算符

既然JavaScript當(dāng)中是沒有類的,那么new運算符又是在干什么呢?這是JavaScript設(shè)計的最讓人誤解的地方之一。JavaScript是一門函數(shù)式編程語言,JavaScript當(dāng)中函數(shù)是一等公民,JavaScript當(dāng)中函數(shù)也是對象,函數(shù)對象在被創(chuàng)建的時候會被添加調(diào)用屬性,比較坑的是JavaScript函數(shù)有兩種調(diào)用方式,一種是加了new關(guān)鍵字的調(diào)用,一種是沒有new關(guān)鍵字的調(diào)用,前者會返回一個對象,后者會返回return語句當(dāng)中的內(nèi)容??紤]下面的一段函數(shù):

function Obj(name){

  this.name=name;

  return name;

}

如果我們用new運算符來調(diào)用:

obj = new Obj("seektruth") //obj會是一個對象:{"name": "seektruth"}

如果我們直接調(diào)用:

obj = Obj("seektruth") //obj會是一個字符串:"seektruth"

確實設(shè)計的挺坑的,我們在調(diào)用的時候需要分清楚是否需要使用new,一般來說需要用new關(guān)鍵字來調(diào)用的函數(shù)會采用大寫開頭。

還有更坑的是如果返回的返回值是一個對象:

function Obj(name){

  this.name=name;

  return {};

}

這樣無論我們是否用new運算符來調(diào)用都會返回return語句里的值:

new Obj("seektruth") //=> {}

Obj("seektruth") //=> {}

設(shè)計的是什么鬼......

對象繼承

原型

前面已經(jīng)說到過JavaScript當(dāng)中是沒有類的,那JavaScript又是怎么來實現(xiàn)繼承的呢?答案是通過原型鏈。在JavaScript當(dāng)中,每個對象都會有一個原型,在創(chuàng)建對象的時候,如果不加說明的話,對象繼承的原型是Object.prototype,函數(shù)對象會繼承Function.prototype(Function.prototype繼承Object.prototype):

Object.prototype // => {}

Function.prototype // => [Function]

我們可以通過對象的__proto__熟悉來查看對象的原型:

a={}

a.__proto__ // => {}

JavaScript通過指定對象的原型來實現(xiàn)繼承,指定對象的原型主要有三種方式,一是在構(gòu)造函數(shù)當(dāng)中指明原型,二是直接修改對象的__proto__屬性,三是利用Object.create函數(shù),下面我們依次來看一看

在構(gòu)造函數(shù)當(dāng)中指定原型

我們可以在構(gòu)造函數(shù)當(dāng)中指定對象的原型:

me={

  "firstName" : "seek",

  "lastName" : "truth" ,

  "getName" : function(){

    return this.firstName+this.lastName; //this相當(dāng)于指向這個對象的指針

  }

}

function Obj(name){

  this.firstName = name;

  this.__proto__ = me; //指定原型為me對象

}

指定了原型之后,我們新建了對象之后就可以訪問原型的屬性:

obj = new Obj("foo"); // => { firstName: 'foo' }

obj.firstName // => foo

obj.lastName // => truth

obj.getName() // => "footruth"

當(dāng)訪問一個對象的時候,首先會嘗試在改對象當(dāng)中尋找該屬性,如果沒有就回到原型當(dāng)中尋找,直到Object.prototype。如果我們在新的對象當(dāng)中重寫了原型當(dāng)中的屬性(方法),那么實際使用的時候我們新寫的屬性(方法)會覆蓋掉原型當(dāng)中的定義,這有點像基于類的語言的函數(shù)重載。

注意如果原型me對象的lastname屬性有改變,因為obj對象是在原型當(dāng)中尋找屬性,那么這個obj對象的lastname屬性也會改變:

me.lastName = "me"

obj.lastName // => "me"

obj.getName() // => "foome"

直接改變對象的原型

我們也可以直接指定(改變)對象的原型:

obj2 = {}

obj2.__proto__ = me

obj2.firstName // => seek

obj2.lastName // => "me"

obj2.getName() // => "seekme"

使用Object.create函數(shù)

盡管說前兩種方法可以解決問題,但是這兩種寫法并不優(yōu)雅,因為JavaScript并不是基于類的語言,第一寫法很容易給人以誤解,JavaScript語言精粹的作者Crockford認為new就不應(yīng)該出現(xiàn)在JavaScript語言當(dāng)中,而推薦使用Object.create函數(shù)來基于原型來創(chuàng)建對象。Object.create函數(shù)的用法很簡單:

obj3 = Object.create(me) // 以me為原型創(chuàng)建新的對象

obj3.firstName // => seek

obj3.lastName // => "me"

obj3.getName() // => "seekme"

obj3 = Object.create(me) 與obj2 = {};obj2.proto = me是等價的,但是前一種寫法更優(yōu)雅也更易于理解。

總結(jié)

JavaScript作為一門基于原型的,函數(shù)式的編程語言在設(shè)計上有很多優(yōu)雅與強大之處,但同時又有很多糟粕和坑,正式如此,JavaScript也是被誤解最多語言。學(xué)習(xí)了JavaScript的對象繼承機制,感覺自己的水平還是大有長進的。

以上這篇淺談JavaScript對象與繼承就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考

更多信息請查看網(wǎng)絡(luò)編程
易賢網(wǎng)手機網(wǎng)站地址:淺談JavaScript對象與繼承
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 加入群交流 | 手機站點 | 投訴建議
工業(yè)和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網(wǎng)安備53010202001879號 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號
聯(lián)系電話:0871-65317125(9:00—18:00) 獲取招聘考試信息及咨詢關(guān)注公眾號:hfpxwx
咨詢QQ:526150442(9:00—18:00)版權(quán)所有:易賢網(wǎng)