摘要:和大多數(shù)瀏覽器的實(shí)現(xiàn)中,每一個對象都有屬性除外,指向?qū)?yīng)的構(gòu)造函數(shù)的屬性。作為構(gòu)造函數(shù)的語法糖,同時有屬性和屬性,因為存在兩條繼承鏈。
前言
es6的class其實(shí)是構(gòu)造函數(shù)的語法糖,但是又有區(qū)別,下面來詳細(xì)分析下class
定義先來看下class的定義的代碼
class Point{ constructor(){} toString(){} } var p = new Point() p.constructor === Point.prototype.contructor//true Object.keys(Point.prototype)//[] Object.getOwnPropertyNames(Point.prototype)//["constructor","toString"]區(qū)別
在類的實(shí)例上調(diào)用方法,就是調(diào)用類的原型上的方法,但是類內(nèi)部的方法是不可枚舉的,構(gòu)造函數(shù)的方法是可枚舉的(是否可被for...in遍歷,object.keys),構(gòu)造函數(shù)可以遍歷除contructor之外的方法
constructor是類默認(rèn)的方法,通過new生成實(shí)例時自動調(diào)用該方法,如果沒有被顯示定義,這個方法會被自動創(chuàng)建。
類只能通過new生成實(shí)例對象,如果像直接調(diào)用class會報錯。
類的所有實(shí)例共享一個原型對象
p2.__proto__ === p1.__proto__;//true
這也就意味著可以通過實(shí)例的__proto__屬性為class添加方法,不推薦使用,因為會影響到其他實(shí)例
class不存在變量提升,這個和繼承有關(guān),必須保證子類在父類之后定義
類和模塊內(nèi)部默認(rèn)都是使用嚴(yán)格模式
class可以自定義原生數(shù)據(jù)結(jié)構(gòu)(Array,String等)的子類,這是es5無法做到的,因為es5是先新建子類的this,再將父類的屬性添加到子類上,由于父類的內(nèi)部屬性子類無法獲取,導(dǎo)致無法繼承原生的構(gòu)造函數(shù)
繼承子類必須在constructor中調(diào)用super方法,否則新建實(shí)例會報錯,因為子類沒有自己的this,而是繼承了父類的this,這和es5中的繼承不一樣,
因為es5中的繼承是先創(chuàng)造子類的實(shí)例對象this,再將父類的方法添加到this上(parent.call(this)),es6中是先繼承父類的實(shí)例對象this,然后再用子類的構(gòu)造函數(shù)修改this。如果子類沒有定義constructor,那么這個方法會被默認(rèn)添加。
在子類的構(gòu)造函數(shù)中,只有調(diào)用super關(guān)鍵字之后,才可使用this關(guān)鍵字,否則會報錯,因為子類實(shí)例的構(gòu)建基于對父類實(shí)例的加工,只有super方法才能返回父類的實(shí)例。
prototype和__proto__
大多數(shù)瀏覽器的es5實(shí)現(xiàn)中,每一個對象都有__proto__屬性(IE8除外),指向?qū)?yīng)的構(gòu)造函數(shù)的prototype屬性。class作為構(gòu)造函數(shù)的語法糖,同時有prototype屬性和__proto__屬性,因為存在兩條繼承鏈。
子類的__proto__屬性表示構(gòu)造函數(shù)的繼承,總是指向父類
子類prototype屬性的__proto__屬性表示方法的繼承,總是指向父類的prototype屬性
class的靜態(tài)方法如果在一個方法前加上static關(guān)鍵字,就表示該方法不會被實(shí)例繼承,而是直接通過類調(diào)用,成為‘靜態(tài)方法’。
看下代碼
class Foo{ static classMethod(){} } Foo.classMethod(); class Bar extends Foo(){ static classMethod(){ return super.classMethod() } } Bar.classMethod();
上面Foo類有靜態(tài)方法classMethod,只能通過Foo.classMethod調(diào)用,不可通過實(shí)例調(diào)用,否則會報錯,父類的靜態(tài)方法可被子類繼承。
class的靜態(tài)屬性靜態(tài)屬性是指class本身的屬性,即class.propname,而不是定義在實(shí)例對象(this)上的屬性。
class Foo{} Foo.prop = 1; Foo.prop //1
上面的方法可以讀、寫Foo類的靜態(tài)屬性prop,但是es6中規(guī)定,class中只有靜態(tài)方法,沒有靜態(tài)屬性
new.target屬性es6為new命令引入了new.target屬性,返回new命令所作用的構(gòu)造函數(shù),如果構(gòu)造函數(shù)不是通過new命令調(diào)用的,那么new.target會返回undefined,因此這個屬性可以判斷構(gòu)造函數(shù)是如何被調(diào)用的
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/97352.html
摘要:中的同名的實(shí)際上就是我們在的原型繼承中使用的構(gòu)造函數(shù),所以中的是對中的構(gòu)造函數(shù)的一種包裝。我們發(fā)現(xiàn),在中設(shè)定的屬性被放在的構(gòu)造函數(shù)中,而方法則以鍵值對的形式傳入一個函數(shù)中。大家是不是對這種繼承模式似曾相識呢對了,這就是所謂的構(gòu)造函數(shù)竊取。 ES6中增加了一些新特性,但從底層的角度來說,只是一些語法糖。但是就我個人來說,如果不了解這些語法糖的本質(zhì),是用不安心的。那我們要如何揭開這些語法糖...
摘要:一用定義一個空類在中在中結(jié)論這個結(jié)果很清晰,原來中的類在中也是定義一個構(gòu)造函數(shù),然后返回出來。 這篇文章用代碼對比的方式解釋ES6中的類如果用我們熟悉的ES5來看是什么樣的。 一、用class定義一個空類在ES6中: class Person { } 在ES5中: var Person = (function () { function Person() { } ...
摘要:請看對應(yīng)版本干了什么可知,相當(dāng)于以前在構(gòu)造函數(shù)里的行為。這種寫法會與上文中寫法有何區(qū)別我們在環(huán)境下運(yùn)行一下,看看這兩種構(gòu)造函數(shù)的有何區(qū)別打印結(jié)果打印結(jié)果結(jié)合上文中關(guān)于原型的論述,仔細(xì)品味這兩者的差別,最好手動嘗試一下。 ES6 class 在ES6版本之前,JavaScript語言并沒有傳統(tǒng)面向?qū)ο笳Z言的class寫法,ES6發(fā)布之后,Babel迅速跟進(jìn),廣大開發(fā)者也很快喜歡上ES6帶...
摘要:不同于其他面向?qū)ο笳Z言,以前的中中沒有類的概念,主要是通過原型的方式來實(shí)現(xiàn)繼承,中引入了原型鏈,并且將原型鏈用來實(shí)現(xiàn)繼承,其核心是利用原型使得一個對象繼承另一個對象的方法和屬性,中原型繼承的關(guān)鍵是將一個實(shí)例的原型對象指向另一個實(shí)例,因此前一 不同于其他面向?qū)ο笳Z言,ES6以前的JavaScript中中沒有class類的概念,主要是通過原型的方式來實(shí)現(xiàn)繼承,JavaScript中引入了原...
摘要:前言見解有限,如有描述不當(dāng)之處,請幫忙及時指出,如有錯誤,會及時修正。倘若用的是中文搜索。所以最終的實(shí)例對象仍然能進(jìn)行正常的原型鏈回溯,回溯到原本的所有原型方法這樣通過一個巧妙的欺騙技巧,就實(shí)現(xiàn)了完美的繼承。 前言 見解有限,如有描述不當(dāng)之處,請幫忙及時指出,如有錯誤,會及時修正。 20180201更新: 修改用詞描述,如組合寄生式改成寄生組合式,修改多處筆誤(感謝@Yao Ding的...
閱讀 5289·2021-09-22 15:59
閱讀 1868·2021-08-23 09:42
閱讀 2570·2019-08-29 18:42
閱讀 3454·2019-08-29 10:55
閱讀 2067·2019-08-27 10:57
閱讀 1764·2019-08-26 18:27
閱讀 2730·2019-08-23 18:26
閱讀 2927·2019-08-23 14:40