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