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