摘要:的傳統生成一個類的方法,需要定義一個構造函數,然后通過的方式生成。定義類父類定義子類,繼承父類可以調用父類的方法如果子類中有構造函數,則必須使用調用。這是因為子類沒有自己的對象,而是繼承父類的對象,然后對其進行加工。
js的傳統生成一個類的方法,需要定義一個構造函數,然后通過new的方式生成。
function Cat() { this.name = "kitty"; this.color = "yellow"; } var cat = new Cat();
js中只有對象,沒有類。這樣的寫法和傳統面向對象語言差異很大,很容易讓新手感到困惑。
定義類ES6添加了類,作為對象的模板。通過class來定義一個類:
//定義類 class Cat { constructor() { this.name = "kitty"; this.color = "yellow"; } //不需要加分號隔開,否則會報錯,而且不用加上function關鍵字 getNames() { console.log("name:" + this.name); } } //使用new操作符得到一個實力對象 let cat = new Cat()
其實ES6的類,完全可以看作構造函數的另一種寫法。
class Cat { //... } typeof Cat // "function" Cat === Cat.prototype.constructor // true //類的數據類型就是函數,類本身就只想構造函數
而且構造函數的prototype屬性,在ES6的“類”上面繼續存在。事實上,類的所有方法都定義在類的prototype屬性上面
class Cat { constructor () { //... } like () { //... } eat(){ //... } } //等同于 Cat.prototype = { constructor () {}, like () {}, eat () {} } let miao = new Cat() miao.constructor === Cat.prototype.constructor // true嚴格模式
類和模塊的內部,默認就是嚴格模式,所以不需要使用use strict指定運行模式。只要你的代碼寫在類或模塊之中,就只有嚴格模式可用。constructor 方法
考慮到未來所有的代碼,其實都是運行在模塊之中,所以 ES6 實際上把整個語言升級到了嚴格模式。
constructor方法是類的默認方法,通過new命令生成對象實例時,自動調用該方法。一個類必須有constructor方法,如果沒有顯式定義,一個空的constructor方法會被默認添加。
類的實例對象用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 表達式
let dogClass = class Dog { getClassName() { return Dog.name; } } let dog = new dogClass(); dog.getClassName() // Dog不存在變量提升
定義類不存在變量提升,只能先定義類后使用,跟函數聲明是有區別的。
//-----函數聲明------- //定義前可以先使用,因為函數聲明提升的緣故,調用合法。 func(); function func(){} //-----定義類--------------- new Cat(); //報錯,Cat is not defined class Cat{}this的指向
類的方法內部如果如果含有this,它默認指向類的實例。但是,必須非常小心,如果多帶帶使用,有可能會報錯。
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, 默認指向Cat類的實例。但是,如果將這個方法提取出來多帶帶使用,this會指向該方法運行時所在的環境,因為找不到print() 方法而導致錯誤。
所以,可以在構造方法中綁定this,這樣就不會找不到print方法了。
class Cat { constructor () { this.eatFish = this.eatFish.bind(this); } //... }
或者使用箭頭函數
class Cat { constructor () { this.eatFish = (kind = "fish") => { this.print(`Hello ${name}`) } } }extends繼承
使用extends 關鍵字實現類之間的繼承。這比在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(); //可以調用父類的方法 c.speakSometing(); // I can speek chinese
如果子類中有constructor構造函數,則必須使用調用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){ //不調super(),則會報錯 this is not defined //必須調用super super(name,age); } coding(){ console.log("coding javascript"); } } var c = new Child("job",30); //可以調用父類的方法 c.speakSometing(); // I can speek chinese
子類必須在constructor方法中調用super方法,否則新建實例時會報錯(this is not defined)。這是因為子類沒有自己的this對象,而是繼承父類的this對象,然后對其進行加工。如果不調用super方法,子類就得不到this對象。
參考:
http://es6.ruanyifeng.com/#docs/class
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/98011.html
摘要:一用定義一個空類在中在中結論這個結果很清晰,原來中的類在中也是定義一個構造函數,然后返回出來。 這篇文章用代碼對比的方式解釋ES6中的類如果用我們熟悉的ES5來看是什么樣的。 一、用class定義一個空類在ES6中: class Person { } 在ES5中: var Person = (function () { function Person() { } ...
摘要:中的同名的實際上就是我們在的原型繼承中使用的構造函數,所以中的是對中的構造函數的一種包裝。我們發現,在中設定的屬性被放在的構造函數中,而方法則以鍵值對的形式傳入一個函數中。大家是不是對這種繼承模式似曾相識呢對了,這就是所謂的構造函數竊取。 ES6中增加了一些新特性,但從底層的角度來說,只是一些語法糖。但是就我個人來說,如果不了解這些語法糖的本質,是用不安心的。那我們要如何揭開這些語法糖...
摘要:和大多數瀏覽器的實現中,每一個對象都有屬性除外,指向對應的構造函數的屬性。作為構造函數的語法糖,同時有屬性和屬性,因為存在兩條繼承鏈。 前言 es6的class其實是構造函數的語法糖,但是又有區別,下面來詳細分析下class 定義 先來看下class的定義的代碼 class Point{ constructor(){} toString(){} } ...
摘要:不同于其他面向對象語言,以前的中中沒有類的概念,主要是通過原型的方式來實現繼承,中引入了原型鏈,并且將原型鏈用來實現繼承,其核心是利用原型使得一個對象繼承另一個對象的方法和屬性,中原型繼承的關鍵是將一個實例的原型對象指向另一個實例,因此前一 不同于其他面向對象語言,ES6以前的JavaScript中中沒有class類的概念,主要是通過原型的方式來實現繼承,JavaScript中引入了原...
摘要:記錄的學習筆記,在回答別人的問題時發現自己的的理解誤差很大的在沒有帶來的的時候,我們編寫的時候很多時候會通過構造函數和原型鏈來添加方法屬性,實現的功能。而是看成是構造函數的寫法。等同于類的實例對象就像使用構造函數一樣使用命令來創建一個實例。 記錄class的學習筆記,在回答別人的問題時發現自己的的理解誤差很大 javascript的class 在沒有es6帶來的class的時候,我們編...
閱讀 2613·2021-09-26 10:17
閱讀 3237·2021-09-22 15:16
閱讀 2147·2021-09-03 10:43
閱讀 3271·2019-08-30 11:23
閱讀 3667·2019-08-29 13:23
閱讀 1316·2019-08-29 11:31
閱讀 3699·2019-08-26 13:52
閱讀 1406·2019-08-26 12:22