摘要:我們都知道在的世界中,幾乎所有東西都是對象,而對象又是通過繼承來層層獲得屬性和方法,首先我們要區分對象和構造函數的區別,中對象繼承的是對象,函數繼承的是函數雖然函數也是對象,只有函數才有原型屬性供它實例的對象繼承,也就是說在中顯示如下字符串
我們都知道在JS的世界中,幾乎所有東西都是對象,而對象又是通過繼承來層層獲得屬性和方法,
var str = new String("mario"); console.dir(str);
首先我們要區分String對象和function String(){}構造函數的區別,JS中對象繼承__proto__的是對象,函數繼承__proto__的是函數(雖然函數也是對象),只有函數才有原型prototype屬性供它實例的對象繼承,也就是說str.__proto__ === String.prototype;在CHROME中顯示如下:
String 0: "m" 1: "a" 2: "r" 3: "i" 4: "o" length: 5 __proto__: String [[PrimitiveValue]]: "mario"
字符串對象的長度是5,初始值是“mario" 繼承于String對象;這個String對象包含了我們熟知的大部分方法和屬性如:
charAt(),charCodeAt()..........,仔細看String對象的屬性和方法也包含一個constructor和__proto__屬性,其中__proto__又指向Object對象,constructor指向的是 構造函數function String(){};
__proto__指向的Object對象包含以下屬性和方法:
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]] : ""
這個Object對象沒有__proto__屬性,說明這個Object對象已經是繼承的終點,所有的對象最終都會繼承于它。
我們在看看最初的String對象有個constructor屬性指向的是構造函數function String(){};說明每個對象都有一個constructor屬性指向創建它的構造函數,所以字符串的constructor會指向String構造函數,那么問題是在JS中,函數也是對象,那么函數的作為對象時又是如何繼承的呢,
實際上所有的構造函數都會繼承一個特殊的匿名函數f(){};這個特殊的匿名函數只有最基本的屬性和方法:
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
這個特殊的匿名函數f,做為對象又繼承了終極對象Object,雖然函數也是對象,但是作為JS中的一等公民,他又有自己的特權,匿名函數f又作為一等公民中的特殊存在,它又有什么特殊的屬性和方法呢,通過上面顯示的屬性和方法我們看到匿名函數f創建它的構造函數是fuction Function(){};不要小看這個構造函數,它是特殊的匿名函數f以自己為原型和繼承自己的屬性創造的,就像女媧按照自己的樣子和能力,創造了第一個人類,其他的人類的原型都是這個人,這個人我們簡稱始祖吧,只有簡單的屬性和方法,
arguments :null caller : null length : 1 name : "Function" prototype : ? () __proto__ : ? ()
幾乎就只有一個名字Function;而創造它的匿名函數 f 就像是女媧;
可以這么說,所有的函數都繼承于這個特殊匿名函數 f ,都有個原型,供它的實例對象繼承,而這個原型又繼承于終極的Object對象。
總結:
JS里的所有對象分為兩類,一般對象,作為函數的對象;
一般對象首先繼承于創建它的原型對象,再繼承于終極Object對象,constructor屬性指向創建它的構造函數;當然作為終極Object對象,雖然沒有在繼承的對象,但是有創造他的構造函數即constructor屬性,function Object(){};
函數繼承于特殊的匿名函數 f ,還有個原型prototype即終極Object對象供它的實例對象繼承,而它的建造者就是已自身為原型和繼承的終極大BOSS function Function(){};
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/85087.html
摘要:相當于在用原型繼承編寫復雜代碼前理解原型繼承模型十分重要。同時,還要清楚代碼中原型鏈的長度,并在必要時結束原型鏈,以避免可能存在的性能問題。 js是一門動態語言,js沒有類的概念,ES6 新增了class 關鍵字,但只是語法糖,JavaScript 仍舊是基于原型。 至于繼承,js的繼承與java這種傳統的繼承不一樣.js是基于原型鏈的繼承. 在javascript里面,每個對象都有一...
摘要:是完全的面向對象語言,它們通過類的形式組織函數和變量,使之不能脫離對象存在。而在基于原型的面向對象方式中,對象則是依靠構造器利用原型構造出來的。 JavaScript 函數式腳本語言特性以及其看似隨意的編寫風格,導致長期以來人們對這一門語言的誤解,即認為 JavaScript 不是一門面向對象的語言,或者只是部分具備一些面向對象的特征。本文將回歸面向對象本意,從對語言感悟的角度闡述為什...
摘要:原型對象是由創建的,因此原型對象的構造函數是構造函數也可以是稱為對象,原型對象也就繼承了其生父構造函數中的數據,也同時繼承了原型對象的數據。當然這條原型鏈中的數據,會被還是還是這類構造函數繼承,但是不會被這些繼承,他們不處于同一個鏈條上。 js中,Function的本質是什么?Object的本質又是什么?js中有幾條原型鏈? showImg(https://segmentfault.c...
摘要:如果要理清原型和原型鏈的關系,首先要明確一下幾個概念中的所有東西都是對象,函數也是對象而且是一種特殊的對象中所有的東西都由衍生而來即所有東西原型鏈的終點指向對象都有一個隱藏的屬性,他指向創建它的構造函數的原型,但是有一個例外,指向的是。 首先要搞明白幾個概念: 函數(function) 函數對象(function object) 本地對象(native object) 內置對象(bu...
摘要:構造函數創建一個對象上邊這個例子,我們通過構造函數創建了一個實例,從這個實例到他的原型到最后得,他們之間得關系,就形成了一個原型鏈和首先上邊這個例子里邊,我們聲明了一個構造函數,在后再這個構造函數里邊有一個的屬性。 構造函數創建一個對象 function Person() { } var person = new Person(); person.name = zhangsan; c...
摘要:構造函數,實例構造函數,是用來創建對象的函數,本質上也是函數。這里剛好解釋一下時,說到的,可以通過實例的訪問構造函數,但是本質上是原型對象的屬性。 前言 最近在學vue,到周末終于有空寫一些東西了(想想又能騙贊,就有點小激動!)。在javascript基礎中,除了閉包之外,繼承也是一個難點。因為考慮到篇幅較長,所以打算分成兩個部分來寫。同樣基于《javascript高級程序設計》,做一...
閱讀 3384·2021-11-22 09:34
閱讀 656·2021-11-19 11:29
閱讀 1354·2019-08-30 15:43
閱讀 2235·2019-08-30 14:24
閱讀 1870·2019-08-29 17:31
閱讀 1228·2019-08-29 17:17
閱讀 2620·2019-08-29 15:38
閱讀 2736·2019-08-26 12:10