摘要:閉包,原型,原型鏈,繼承對象若干屬性的集合輸出的集中類型標(biāo)識,其中上面的四種屬于簡單的值類型,不是對象。在實(shí)際應(yīng)用中如何區(qū)分一個屬性到底是基本的還是從原型中找到的呢,特別是在循環(huán)中由于所有的對象的原型鏈都會找到,因此所有的對象都會有的方法。
閉包,原型,原型鏈,繼承
對象——若干屬性的集合typeof輸出的集中類型標(biāo)識,
其中上面的四種(undefined, number, string, boolean)屬于簡單的值類型,不是對象。
剩下的幾種情況——函數(shù)、數(shù)組、對象、null、new Number(10)都是對象。他們都是引用類型。
判斷一個變量是不是對象非常簡單。值類型的類型判斷用typeof,引用類型的類型判斷用instanceof。
一切(引用類型)都是對象,對象是屬性的集合
函數(shù)和對象的關(guān)系(雞生蛋蛋生雞)
對象都是通過函數(shù)創(chuàng)建的
console.log(typeof (Object)); // function console.log(typeof (Array)); // functionprototype原型
javascript默認(rèn)的給函數(shù)一個屬性——prototype。每個函數(shù)都有一個屬性叫做prototype。
這個prototype的屬性值是一個對象(屬性的集合,再次強(qiáng)調(diào)?。?,默認(rèn)的只有一個叫做constructor的屬性,指向這個函數(shù)本身。
每個對象都有一個隱藏的屬性——“__proto__”,這個屬性引用了創(chuàng)建這個對象的函數(shù)的prototype。
這里的"__proto__"成為“隱式原型”
隱式原型__proto__每個函數(shù)function都有一個prototype,即原型。
每個對象都有一個__proto__,可成為隱式原型。
(這個__proto__是一個隱藏的屬性,javascript不希望開發(fā)者用到這個屬性值,有的低版本瀏覽器甚至不支持這個屬性值。所以你在Visual Studio 2012這樣很高級很智能的編輯器中,都不會有__proto__的智能提示,但是你不用管它,直接寫出來就是了。)
每個對象都有一個__proto__屬性,指向創(chuàng)建該對象的函數(shù)的prototype
Object.prototype確實(shí)一個特例——它的__proto__指向的是null
Object.__proto__ === Function.prototype
Function是被自身創(chuàng)建的。所以它的__proto__指向了自身的Prototype
Function.prototype指向的對象,它的__proto__也指向Object.prototype
instanceoftypeof在判斷到引用類型的時候,返回值只有object/function,你不知道它到底是一個object對象,還是數(shù)組,還是new Number等等。
這個時候就需要用到instanceof。
Instanceof運(yùn)算符的第一個變量是一個對象,暫時稱為A;第二個變量一般是一個函數(shù),暫時稱為B。
Instanceof的判斷隊(duì)則是:沿著A的__proto__這條線來找,同時沿著B的prototype這條線來找,如果兩條線能找到同一個引用,即同一個對象,那么就返回true。如果找到終點(diǎn)還未重合,則返回false。
notice
一條線一條線挨著分析
instanceof表示的就是一種繼承關(guān)系,或者原型鏈的結(jié)構(gòu)
javascript中的繼承是通過原型鏈來體現(xiàn)的
訪問一個對象的屬性時,先在基本屬性中查找,如果沒有,再沿著__proto__這條鏈向上找,這就是原型鏈。
在實(shí)際應(yīng)用中如何區(qū)分一個屬性到底是基本的還是從原型中找到的呢?hasOwnProperty,特別是在for…in…循環(huán)中
由于所有的對象的原型鏈都會找到Object.prototype,因此所有的對象都會有Object.prototype的方法。這就是所謂的“繼承”。
每個函數(shù)都有call,apply方法,都有l(wèi)ength,arguments,caller等屬性。為什么每個函數(shù)都有?這肯定是“繼承”的。函數(shù)由Function函數(shù)創(chuàng)建,因此繼承的Function.prototype中的方法。
hasOwnProperty是Function.prototype繼承自O(shè)bject.prototype的方法。
原型的靈活性在Java和C#中,你可以簡單的理解class是一個模子,對象就是被這個模子壓出來的一批一批月餅(中秋節(jié)剛過完)。壓個啥樣,就得是個啥樣,不能隨便動,動一動就壞了。
而在javascript中,就沒有模子了,月餅被換成了面團(tuán),你可以捏成自己想要的樣子。
對象或者函數(shù),剛開始new出來之后,可能啥屬性都沒有。但是你可以這會兒加一個,過一會兒在加兩個,非常靈活。
Object和Array的toString()方法不一樣??隙ㄊ茿rray.prototype.toString()方法做了修改
如果你要添加內(nèi)置方法的原型屬性,最好做一步判斷,如果該屬性不存在,則添加。如果本來就存在,就沒必要再添加了。
執(zhí)行上下文在一段js代碼拿過來真正一句一句運(yùn)行之前,瀏覽器已經(jīng)做了一些“準(zhǔn)備工作”,其中就包括對變量的聲明,而不是賦值。變量賦值是在賦值語句執(zhí)行的時候進(jìn)行的。
我們總結(jié)一下,在“準(zhǔn)備工作”中完成了哪些工作:
變量、函數(shù)表達(dá)式——變量聲明,默認(rèn)賦值為undefined;
this——賦值;
函數(shù)聲明——賦值;
這三種數(shù)據(jù)的準(zhǔn)備情況我們稱之為“執(zhí)行上下文”或者“執(zhí)行上下文環(huán)境”。
這個“代碼段”其實(shí)分三種情況——全局代碼,函數(shù)體,eval代碼。
函數(shù)每被調(diào)用一次,都會產(chǎn)生一個新的執(zhí)行上下文環(huán)境。
函數(shù)在定義的時候(不是調(diào)用的時候),就已經(jīng)確定了函數(shù)體內(nèi)部自由變量的作用域。
給執(zhí)行上下文環(huán)境下一個通俗的定義——在執(zhí)行代碼之前,把將要用到的所有的變量都事先拿出來,有的直接賦值了,有的先用undefined占個空。
thisthis的取值,分四種情況
在函數(shù)中this到底取何值,是在函數(shù)真正被調(diào)用執(zhí)行的時候確定的,函數(shù)定義的時候確定不了。
因?yàn)閠his的取值是執(zhí)行上下文環(huán)境的一部分,每次調(diào)用函數(shù),都會產(chǎn)生一個新的執(zhí)行上下文環(huán)境。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/91362.html
摘要:是完全的面向?qū)ο笳Z言,它們通過類的形式組織函數(shù)和變量,使之不能脫離對象存在。而在基于原型的面向?qū)ο蠓绞街?,對象則是依靠構(gòu)造器利用原型構(gòu)造出來的。 JavaScript 函數(shù)式腳本語言特性以及其看似隨意的編寫風(fēng)格,導(dǎo)致長期以來人們對這一門語言的誤解,即認(rèn)為 JavaScript 不是一門面向?qū)ο蟮恼Z言,或者只是部分具備一些面向?qū)ο蟮奶卣?。本文將回歸面向?qū)ο蟊疽?,從對語言感悟的角度闡述為什...
摘要:一面向?qū)ο蟾拍蠲嫦驅(qū)ο缶褪鞘褂脤ο蟆R虼嗽跇?gòu)造函數(shù)中表示剛剛創(chuàng)建出來的對象。在構(gòu)造函數(shù)中利用對象的動態(tài)特性為其對象添加成員。 一、面向?qū)ο?1.1 概念 面向?qū)ο缶褪鞘褂脤ο?。面向?qū)ο箝_發(fā)就是使用對象開發(fā)。 面向過程就是用過程的方式進(jìn)行開發(fā)。面向?qū)ο笫菍γ嫦蜻^程的封裝。 1.2 三大特性 抽象性所謂的抽象性就是:如果需要一個對象描述數(shù)據(jù),需要抽取這個對象的核心數(shù)據(jù) 提出需要的核心...
摘要:示例構(gòu)造函數(shù)繼承實(shí)例對象其次,我們還可以使用中的新語法等關(guān)鍵字來實(shí)現(xiàn)繼承。對象的屬性是該對象的構(gòu)造函數(shù)的屬性?;谏线厴?gòu)造函數(shù)繼承代碼作用域與命名空間如果了解的用法,那么就應(yīng)該只要有塊級作用域和函數(shù)作用域。 JavaScript數(shù)據(jù)類型 JavaScript中有哪些基本數(shù)據(jù)類型 undefined、null、number、string、boolean、symbol(es6中新增)為啥沒...
摘要:因?yàn)槲覀冇眠@個函數(shù)來構(gòu)造對象,所以我們也把稱作構(gòu)造函數(shù)。所以通過定義構(gòu)造函數(shù),就相當(dāng)于定義了一個類,通過關(guān)鍵字,即可生成一個實(shí)例化的對象。 一、序言 ??和其他面向?qū)ο蟮恼Z言(如Java)不同,Javascript語言對類的實(shí)現(xiàn)和繼承的實(shí)現(xiàn)沒有標(biāo)準(zhǔn)的定義,而是將這些交給了程序員,讓程序員更加靈活地(當(dāng)然剛開始也更加頭疼)去定義類,實(shí)現(xiàn)繼承。(以下不討論ES6中利用class、exten...
摘要:當(dāng)解釋器尋找引用值時,會首先檢索其在棧中的地址,取得地址后從堆中獲得實(shí)體如何實(shí)現(xiàn)繼承構(gòu)造繼承原型繼承實(shí)例繼承拷貝繼承原型機(jī)制或和方法去實(shí)現(xiàn)較簡單,建議使用構(gòu)造函數(shù)與原型混合方式。它是基于的一個子集。 JavaScript介紹js的基本數(shù)據(jù)類型。Undefined、Null、Boolean、Number、Stri...
閱讀 1094·2021-11-22 14:56
閱讀 1531·2019-08-30 15:55
閱讀 3372·2019-08-30 15:45
閱讀 1667·2019-08-30 13:03
閱讀 2879·2019-08-29 18:47
閱讀 3342·2019-08-29 11:09
閱讀 2650·2019-08-26 18:36
閱讀 2625·2019-08-26 13:55