摘要:我們都知道在的世界中,幾乎所有東西都是對(duì)象,而對(duì)象又是通過(guò)繼承來(lái)層層獲得屬性和方法,首先我們要區(qū)分對(duì)象和構(gòu)造函數(shù)的區(qū)別,中對(duì)象繼承的是對(duì)象,函數(shù)繼承的是函數(shù)雖然函數(shù)也是對(duì)象,只有函數(shù)才有原型屬性供它實(shí)例的對(duì)象繼承,也就是說(shuō)在中顯示如下字符串
我們都知道在JS的世界中,幾乎所有東西都是對(duì)象,而對(duì)象又是通過(guò)繼承來(lái)層層獲得屬性和方法,
var str = new String("mario"); console.dir(str);
首先我們要區(qū)分String對(duì)象和function String(){}構(gòu)造函數(shù)的區(qū)別,JS中對(duì)象繼承__proto__的是對(duì)象,函數(shù)繼承__proto__的是函數(shù)(雖然函數(shù)也是對(duì)象),只有函數(shù)才有原型prototype屬性供它實(shí)例的對(duì)象繼承,也就是說(shuō)str.__proto__ === String.prototype;在CHROME中顯示如下:
String 0: "m" 1: "a" 2: "r" 3: "i" 4: "o" length: 5 __proto__: String [[PrimitiveValue]]: "mario"
字符串對(duì)象的長(zhǎng)度是5,初始值是“mario" 繼承于String對(duì)象;這個(gè)String對(duì)象包含了我們熟知的大部分方法和屬性如:
charAt(),charCodeAt()..........,仔細(xì)看String對(duì)象的屬性和方法也包含一個(gè)constructor和__proto__屬性,其中__proto__又指向Object對(duì)象,constructor指向的是 構(gòu)造函數(shù)function String(){};
__proto__指向的Object對(duì)象包含以下屬性和方法:
constructor :? Object() hasOwnProperty : ? hasOwnProperty() isPrototypeOf : ? isPrototypeOf() propertyIsEnumerable : ? propertyIsEnumerable() toLocaleString : ? toLocaleString() toString : ? toString() valueOf : ? valueOf() __defineGetter__ : ? __defineGetter__() __defineSetter__ : ? __defineSetter__() __lookupGetter__ : ? __lookupGetter__() __lookupSetter__ : ? __lookupSetter__() get __proto__ : ? __proto__() set __proto__ : ? __proto__() [[PrimitiveValue]] : ""
這個(gè)Object對(duì)象沒(méi)有__proto__屬性,說(shuō)明這個(gè)Object對(duì)象已經(jīng)是繼承的終點(diǎn),所有的對(duì)象最終都會(huì)繼承于它。
我們?cè)诳纯醋畛醯腟tring對(duì)象有個(gè)constructor屬性指向的是構(gòu)造函數(shù)function String(){};說(shuō)明每個(gè)對(duì)象都有一個(gè)constructor屬性指向創(chuàng)建它的構(gòu)造函數(shù),所以字符串的constructor會(huì)指向String構(gòu)造函數(shù),那么問(wèn)題是在JS中,函數(shù)也是對(duì)象,那么函數(shù)的作為對(duì)象時(shí)又是如何繼承的呢,
實(shí)際上所有的構(gòu)造函數(shù)都會(huì)繼承一個(gè)特殊的匿名函數(shù)f(){};這個(gè)特殊的匿名函數(shù)只有最基本的屬性和方法:
apply : ? apply() arguments : (...) bind : ? bind() call : ? call() caller : (...) constructor : ? Function() length : 0 name : "" toString : ? toString() Symbol(Symbol.hasInstance) : ? [Symbol.hasInstance]() get arguments : ? ThrowTypeError() set arguments : ? ThrowTypeError() get caller : ? ThrowTypeError() set caller : ? ThrowTypeError() __proto__ : Object
這個(gè)特殊的匿名函數(shù)f,做為對(duì)象又繼承了終極對(duì)象Object,雖然函數(shù)也是對(duì)象,但是作為JS中的一等公民,他又有自己的特權(quán),匿名函數(shù)f又作為一等公民中的特殊存在,它又有什么特殊的屬性和方法呢,通過(guò)上面顯示的屬性和方法我們看到匿名函數(shù)f創(chuàng)建它的構(gòu)造函數(shù)是fuction Function(){};不要小看這個(gè)構(gòu)造函數(shù),它是特殊的匿名函數(shù)f以自己為原型和繼承自己的屬性創(chuàng)造的,就像女?huà)z按照自己的樣子和能力,創(chuàng)造了第一個(gè)人類,其他的人類的原型都是這個(gè)人,這個(gè)人我們簡(jiǎn)稱始祖吧,只有簡(jiǎn)單的屬性和方法,
arguments :null caller : null length : 1 name : "Function" prototype : ? () __proto__ : ? ()
幾乎就只有一個(gè)名字Function;而創(chuàng)造它的匿名函數(shù) f 就像是女?huà)z;
可以這么說(shuō),所有的函數(shù)都繼承于這個(gè)特殊匿名函數(shù) f ,都有個(gè)原型,供它的實(shí)例對(duì)象繼承,而這個(gè)原型又繼承于終極的Object對(duì)象。
總結(jié):
JS里的所有對(duì)象分為兩類,一般對(duì)象,作為函數(shù)的對(duì)象;
一般對(duì)象首先繼承于創(chuàng)建它的原型對(duì)象,再繼承于終極Object對(duì)象,constructor屬性指向創(chuàng)建它的構(gòu)造函數(shù);當(dāng)然作為終極Object對(duì)象,雖然沒(méi)有在繼承的對(duì)象,但是有創(chuàng)造他的構(gòu)造函數(shù)即constructor屬性,function Object(){};
函數(shù)繼承于特殊的匿名函數(shù) f ,還有個(gè)原型prototype即終極Object對(duì)象供它的實(shí)例對(duì)象繼承,而它的建造者就是已自身為原型和繼承的終極大BOSS function Function(){};
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/85087.html
摘要:相當(dāng)于在用原型繼承編寫(xiě)復(fù)雜代碼前理解原型繼承模型十分重要。同時(shí),還要清楚代碼中原型鏈的長(zhǎng)度,并在必要時(shí)結(jié)束原型鏈,以避免可能存在的性能問(wèn)題。 js是一門動(dòng)態(tài)語(yǔ)言,js沒(méi)有類的概念,ES6 新增了class 關(guān)鍵字,但只是語(yǔ)法糖,JavaScript 仍舊是基于原型。 至于繼承,js的繼承與java這種傳統(tǒng)的繼承不一樣.js是基于原型鏈的繼承. 在javascript里面,每個(gè)對(duì)象都有一...
摘要:是完全的面向?qū)ο笳Z(yǔ)言,它們通過(guò)類的形式組織函數(shù)和變量,使之不能脫離對(duì)象存在。而在基于原型的面向?qū)ο蠓绞街?,?duì)象則是依靠構(gòu)造器利用原型構(gòu)造出來(lái)的。 JavaScript 函數(shù)式腳本語(yǔ)言特性以及其看似隨意的編寫(xiě)風(fēng)格,導(dǎo)致長(zhǎng)期以來(lái)人們對(duì)這一門語(yǔ)言的誤解,即認(rèn)為 JavaScript 不是一門面向?qū)ο蟮恼Z(yǔ)言,或者只是部分具備一些面向?qū)ο蟮奶卣鳌1疚膶⒒貧w面向?qū)ο蟊疽?,從?duì)語(yǔ)言感悟的角度闡述為什...
摘要:原型對(duì)象是由創(chuàng)建的,因此原型對(duì)象的構(gòu)造函數(shù)是構(gòu)造函數(shù)也可以是稱為對(duì)象,原型對(duì)象也就繼承了其生父構(gòu)造函數(shù)中的數(shù)據(jù),也同時(shí)繼承了原型對(duì)象的數(shù)據(jù)。當(dāng)然這條原型鏈中的數(shù)據(jù),會(huì)被還是還是這類構(gòu)造函數(shù)繼承,但是不會(huì)被這些繼承,他們不處于同一個(gè)鏈條上。 js中,F(xiàn)unction的本質(zhì)是什么?Object的本質(zhì)又是什么?js中有幾條原型鏈? showImg(https://segmentfault.c...
摘要:如果要理清原型和原型鏈的關(guān)系,首先要明確一下幾個(gè)概念中的所有東西都是對(duì)象,函數(shù)也是對(duì)象而且是一種特殊的對(duì)象中所有的東西都由衍生而來(lái)即所有東西原型鏈的終點(diǎn)指向?qū)ο蠖加幸粋€(gè)隱藏的屬性,他指向創(chuàng)建它的構(gòu)造函數(shù)的原型,但是有一個(gè)例外,指向的是。 首先要搞明白幾個(gè)概念: 函數(shù)(function) 函數(shù)對(duì)象(function object) 本地對(duì)象(native object) 內(nèi)置對(duì)象(bu...
摘要:構(gòu)造函數(shù)創(chuàng)建一個(gè)對(duì)象上邊這個(gè)例子,我們通過(guò)構(gòu)造函數(shù)創(chuàng)建了一個(gè)實(shí)例,從這個(gè)實(shí)例到他的原型到最后得,他們之間得關(guān)系,就形成了一個(gè)原型鏈和首先上邊這個(gè)例子里邊,我們聲明了一個(gè)構(gòu)造函數(shù),在后再這個(gè)構(gòu)造函數(shù)里邊有一個(gè)的屬性。 構(gòu)造函數(shù)創(chuàng)建一個(gè)對(duì)象 function Person() { } var person = new Person(); person.name = zhangsan; c...
摘要:構(gòu)造函數(shù),實(shí)例構(gòu)造函數(shù),是用來(lái)創(chuàng)建對(duì)象的函數(shù),本質(zhì)上也是函數(shù)。這里剛好解釋一下時(shí),說(shuō)到的,可以通過(guò)實(shí)例的訪問(wèn)構(gòu)造函數(shù),但是本質(zhì)上是原型對(duì)象的屬性。 前言 最近在學(xué)vue,到周末終于有空寫(xiě)一些東西了(想想又能騙贊,就有點(diǎn)小激動(dòng)?。?。在javascript基礎(chǔ)中,除了閉包之外,繼承也是一個(gè)難點(diǎn)。因?yàn)榭紤]到篇幅較長(zhǎng),所以打算分成兩個(gè)部分來(lái)寫(xiě)。同樣基于《javascript高級(jí)程序設(shè)計(jì)》,做一...
閱讀 3407·2021-11-22 09:34
閱讀 674·2021-11-19 11:29
閱讀 1380·2019-08-30 15:43
閱讀 2257·2019-08-30 14:24
閱讀 1895·2019-08-29 17:31
閱讀 1251·2019-08-29 17:17
閱讀 2639·2019-08-29 15:38
閱讀 2776·2019-08-26 12:10