摘要:的傳統(tǒng)生成一個(gè)類的方法,需要定義一個(gè)構(gòu)造函數(shù),然后通過(guò)的方式生成。定義類父類定義子類,繼承父類可以調(diào)用父類的方法如果子類中有構(gòu)造函數(shù),則必須使用調(diào)用。這是因?yàn)樽宇悰](méi)有自己的對(duì)象,而是繼承父類的對(duì)象,然后對(duì)其進(jìn)行加工。
js的傳統(tǒng)生成一個(gè)類的方法,需要定義一個(gè)構(gòu)造函數(shù),然后通過(guò)new的方式生成。
function Cat() { this.name = "kitty"; this.color = "yellow"; } var cat = new Cat();
js中只有對(duì)象,沒(méi)有類。這樣的寫(xiě)法和傳統(tǒng)面向?qū)ο笳Z(yǔ)言差異很大,很容易讓新手感到困惑。
定義類ES6添加了類,作為對(duì)象的模板。通過(guò)class來(lái)定義一個(gè)類:
//定義類 class Cat { constructor() { this.name = "kitty"; this.color = "yellow"; } //不需要加分號(hào)隔開(kāi),否則會(huì)報(bào)錯(cuò),而且不用加上function關(guān)鍵字 getNames() { console.log("name:" + this.name); } } //使用new操作符得到一個(gè)實(shí)力對(duì)象 let cat = new Cat()
其實(shí)ES6的類,完全可以看作構(gòu)造函數(shù)的另一種寫(xiě)法。
class Cat { //... } typeof Cat // "function" Cat === Cat.prototype.constructor // true //類的數(shù)據(jù)類型就是函數(shù),類本身就只想構(gòu)造函數(shù)
而且構(gòu)造函數(shù)的prototype屬性,在ES6的“類”上面繼續(xù)存在。事實(shí)上,類的所有方法都定義在類的prototype屬性上面
class Cat { constructor () { //... } like () { //... } eat(){ //... } } //等同于 Cat.prototype = { constructor () {}, like () {}, eat () {} } let miao = new Cat() miao.constructor === Cat.prototype.constructor // true嚴(yán)格模式
類和模塊的內(nèi)部,默認(rèn)就是嚴(yán)格模式,所以不需要使用use strict指定運(yùn)行模式。只要你的代碼寫(xiě)在類或模塊之中,就只有嚴(yán)格模式可用。constructor 方法
考慮到未來(lái)所有的代碼,其實(shí)都是運(yùn)行在模塊之中,所以 ES6 實(shí)際上把整個(gè)語(yǔ)言升級(jí)到了嚴(yán)格模式。
constructor方法是類的默認(rèn)方法,通過(guò)new命令生成對(duì)象實(shí)例時(shí),自動(dòng)調(diào)用該方法。一個(gè)類必須有constructor方法,如果沒(méi)有顯式定義,一個(gè)空的constructor方法會(huì)被默認(rèn)添加。
類的實(shí)例對(duì)象用new命令生成類的實(shí)例對(duì)象
class Cat { //... } var cat = Cat ( "kitty" , "blue");//報(bào)錯(cuò) var cat = new Cat ( "kitty" , "blue"); //正確
實(shí)例的屬性定義在原型上
//定義類 class Cat { constructor() { this.name = "kitty"; this.color = "yellow"; } getNames() { console.log("name:" + this.name); } } //使用new操作符得到一個(gè)實(shí)例對(duì)象 let cat = new Cat() cat.getNames() // name:kitty cat.hasOwnProperty("name")//true cat.hasOwnProperty("getNames")//false cat.__proto__.hasOwnProperty("getNames")//true
和ES5一樣,類的所有實(shí)例共享一個(gè)原型對(duì)象
let cat1 = new Cat(); let cat2 = new Cat(); cat1.__proto__ === cat2.__proto__Class 表達(dá)式
let dogClass = class Dog { getClassName() { return Dog.name; } } let dog = new dogClass(); dog.getClassName() // Dog不存在變量提升
定義類不存在變量提升,只能先定義類后使用,跟函數(shù)聲明是有區(qū)別的。
//-----函數(shù)聲明------- //定義前可以先使用,因?yàn)楹瘮?shù)聲明提升的緣故,調(diào)用合法。 func(); function func(){} //-----定義類--------------- new Cat(); //報(bào)錯(cuò),Cat is not defined class Cat{}this的指向
類的方法內(nèi)部如果如果含有this,它默認(rèn)指向類的實(shí)例。但是,必須非常小心,如果多帶帶使用,有可能會(huì)報(bào)錯(cuò)。
class Cat { eatFish ( kind = "fish"){ this.print (`Hello ${fish}`); } print(str){ console.log(str) } } let cat = new Cat(); const { eatFish } = cat; eatFish;// TypeError: Cannot read property "print" of undefined
上面代碼中,eatFish方法中的this, 默認(rèn)指向Cat類的實(shí)例。但是,如果將這個(gè)方法提取出來(lái)多帶帶使用,this會(huì)指向該方法運(yùn)行時(shí)所在的環(huán)境,因?yàn)檎也坏絧rint() 方法而導(dǎo)致錯(cuò)誤。
所以,可以在構(gòu)造方法中綁定this,這樣就不會(huì)找不到print方法了。
class Cat { constructor () { this.eatFish = this.eatFish.bind(this); } //... }
或者使用箭頭函數(shù)
class Cat { constructor () { this.eatFish = (kind = "fish") => { this.print(`Hello ${name}`) } } }extends繼承
使用extends 關(guān)鍵字實(shí)現(xiàn)類之間的繼承。這比在ES5中使用繼承要方便很多。
//定義類父類 class Parent { constructor(name,age){ this.name = name; this.age = age; } speakSometing(){ console.log("I can speek chinese"); } } //定義子類,繼承父類 class Child extends Parent { coding(){ console.log("coding javascript"); } } var c = new Child(); //可以調(diào)用父類的方法 c.speakSometing(); // I can speek chinese
如果子類中有constructor構(gòu)造函數(shù),則必須使用調(diào)用super。
//定義父類 class Parent { constructor(name,age){ this.name = name; this.age = age; } speakSometing(){ console.log("I can speek chinese"); } } //定義子類,繼承父類 class Child extends Parent { constructor(name,age){ //不調(diào)super(),則會(huì)報(bào)錯(cuò) this is not defined //必須調(diào)用super super(name,age); } coding(){ console.log("coding javascript"); } } var c = new Child("job",30); //可以調(diào)用父類的方法 c.speakSometing(); // I can speek chinese
子類必須在constructor方法中調(diào)用super方法,否則新建實(shí)例時(shí)會(huì)報(bào)錯(cuò)(this is not defined)。這是因?yàn)樽宇悰](méi)有自己的this對(duì)象,而是繼承父類的this對(duì)象,然后對(duì)其進(jìn)行加工。如果不調(diào)用super方法,子類就得不到this對(duì)象。
參考:
http://es6.ruanyifeng.com/#docs/class
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/98011.html
摘要:一用定義一個(gè)空類在中在中結(jié)論這個(gè)結(jié)果很清晰,原來(lái)中的類在中也是定義一個(gè)構(gòu)造函數(shù),然后返回出來(lái)。 這篇文章用代碼對(duì)比的方式解釋ES6中的類如果用我們熟悉的ES5來(lái)看是什么樣的。 一、用class定義一個(gè)空類在ES6中: class Person { } 在ES5中: var Person = (function () { function Person() { } ...
摘要:中的同名的實(shí)際上就是我們?cè)诘脑屠^承中使用的構(gòu)造函數(shù),所以中的是對(duì)中的構(gòu)造函數(shù)的一種包裝。我們發(fā)現(xiàn),在中設(shè)定的屬性被放在的構(gòu)造函數(shù)中,而方法則以鍵值對(duì)的形式傳入一個(gè)函數(shù)中。大家是不是對(duì)這種繼承模式似曾相識(shí)呢對(duì)了,這就是所謂的構(gòu)造函數(shù)竊取。 ES6中增加了一些新特性,但從底層的角度來(lái)說(shuō),只是一些語(yǔ)法糖。但是就我個(gè)人來(lái)說(shuō),如果不了解這些語(yǔ)法糖的本質(zhì),是用不安心的。那我們要如何揭開(kāi)這些語(yǔ)法糖...
摘要:和大多數(shù)瀏覽器的實(shí)現(xiàn)中,每一個(gè)對(duì)象都有屬性除外,指向?qū)?yīng)的構(gòu)造函數(shù)的屬性。作為構(gòu)造函數(shù)的語(yǔ)法糖,同時(shí)有屬性和屬性,因?yàn)榇嬖趦蓷l繼承鏈。 前言 es6的class其實(shí)是構(gòu)造函數(shù)的語(yǔ)法糖,但是又有區(qū)別,下面來(lái)詳細(xì)分析下class 定義 先來(lái)看下class的定義的代碼 class Point{ constructor(){} toString(){} } ...
摘要:不同于其他面向?qū)ο笳Z(yǔ)言,以前的中中沒(méi)有類的概念,主要是通過(guò)原型的方式來(lái)實(shí)現(xiàn)繼承,中引入了原型鏈,并且將原型鏈用來(lái)實(shí)現(xiàn)繼承,其核心是利用原型使得一個(gè)對(duì)象繼承另一個(gè)對(duì)象的方法和屬性,中原型繼承的關(guān)鍵是將一個(gè)實(shí)例的原型對(duì)象指向另一個(gè)實(shí)例,因此前一 不同于其他面向?qū)ο笳Z(yǔ)言,ES6以前的JavaScript中中沒(méi)有class類的概念,主要是通過(guò)原型的方式來(lái)實(shí)現(xiàn)繼承,JavaScript中引入了原...
摘要:記錄的學(xué)習(xí)筆記,在回答別人的問(wèn)題時(shí)發(fā)現(xiàn)自己的的理解誤差很大的在沒(méi)有帶來(lái)的的時(shí)候,我們編寫(xiě)的時(shí)候很多時(shí)候會(huì)通過(guò)構(gòu)造函數(shù)和原型鏈來(lái)添加方法屬性,實(shí)現(xiàn)的功能。而是看成是構(gòu)造函數(shù)的寫(xiě)法。等同于類的實(shí)例對(duì)象就像使用構(gòu)造函數(shù)一樣使用命令來(lái)創(chuàng)建一個(gè)實(shí)例。 記錄class的學(xué)習(xí)筆記,在回答別人的問(wèn)題時(shí)發(fā)現(xiàn)自己的的理解誤差很大 javascript的class 在沒(méi)有es6帶來(lái)的class的時(shí)候,我們編...
閱讀 2649·2021-09-26 10:17
閱讀 3258·2021-09-22 15:16
閱讀 2166·2021-09-03 10:43
閱讀 3293·2019-08-30 11:23
閱讀 3688·2019-08-29 13:23
閱讀 1338·2019-08-29 11:31
閱讀 3720·2019-08-26 13:52
閱讀 1430·2019-08-26 12:22