摘要:語言傳統方法通過構造函數定義并生成新對象,引入了這個概念作為對象的模板,通過關鍵字可以定義類?;菊Z法等同于上面的代碼表明,類的數據類型就是函數,類本身指向構造函數。屬性引入了屬性,在構造函數中返回命令所作用的構造函數。
JS語言傳統方法通過構造函數定義并生成新對象,ES6引入了Class這個概念作為對象的模板,通過class關鍵字可以定義類。
基本語法function Point(x, y) { this.x = x; this.y = y; } Point.prototype.toString = function () { return "(" + this.x + "," + this.y + ")"; } Point.protortype.doStuff = function () { console.log("stuff"); } // 等同于 class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return "(" + this.x + "," + this.y + ")"; } doStuff() { console.log("stuff"); } } typeof Point // "function" Point === Point.prototype.constructor // true
上面的代碼表明,類的數據類型就是函數,類本身指向構造函數。類的所有方法都定義在類的prototype屬性上。在類的實例上調用方法,就是在調用原型上的方法。constructor方法是類的默認方法,通過new命令生成對象實例時自動調用該方法。如果沒有顯示定義,一個空的construtor方法會被默認添加。
類的實例對象生成實例對象的寫法和ES5一樣,也是使用new命令,不同于ES5,如果忘記加new將會報錯。
class Point { } // 等同于 class Point { constructor() { } } var b = new Point(2, 3); // 生成Point實例 var c = Pint(2, 3) // 報錯Class表達式
與函數一樣,Class可以使用表達式的形式定義。
const MyClass = class Me { getClassName() { return Me.Name; } }
需要注意的是這個類的名字是MyClass,而不是Me,Me只在Class內部有定義指代當前類。如果Class內部沒有用到,那么可以省略Me。
let int = new MyClass(); int.getClassName() // Me Me.Name // 報錯 const MyClass = class { getClassName() { return Me.Name; } } # 不存在變量提升 類不存在變量提升,與ES5完全不同。
new Foo() // 報錯
class Foo {}
# Class的實例屬性 Class的實例屬性可以用等式寫入類的定義中。
class MyClass {
myProp = 42;
constructor() {
console.log(this.myProp); // 42
}
}
ES6引入了new.target屬性,(在構造函數中)返回new命令所作用的構造函數。如果構造函數不是通過new命令調用,那么new.target將會返回undefined,可以利用這個屬性確定構造函數是怎么調用的。
function Person(name) { if (new.target !== undefined) { this.name = name; } else { throw new Error("必須使用new生成實例") } /*另一種寫法 if (new.target == Person) { this.name = name; } else { throw new Error("必須使用new生成實例") }*/ } var Person = new Person("張三"); // 正確 var notAPerson = Person.call(person, "張三"); //報錯
Class內部調用new.target,返回當前Class。
class Rectangle { constructor(length, width) { console.log(new.target === Rectangle); this.length = length; this.width = width; } } var obj = new Rectangle(3, 4); // 輸出true
值得注意的是,之類基礎父類時new.target會返回之類。利用這個特點,可以寫出不能獨立使用而是必須繼承后才能使用的類。
class Shape { constructor() { if (new.target === Shape) { throw new Error("本類不能實例化"); } } } class Rectangle extends Shape { constructor(length, width) { super(); //... } } var x = new Shape(); // 報錯 var y = new Rectangle(); // 正確Class的繼承
Class可以通過extends關鍵字實現繼承,之類必須在constructor方法中調用super方法,否則新建實例會報錯。這是因為子類沒有自己的this對象,而是繼承父類的this對象。如果子類沒有定義constructor方法,那么constructor方法(調用super)會被默認添加。
class Point { /* ... */} class ColorPoint extends Point { constructor() { //此處應調用super(); } } let cp = new ColorPoint(); // 報錯
另一個注意點是,在子類的構造函數中只有在調用super之后才可以使用this關鍵字,否則會報錯。
class Point { constructor(x, y) { this.x = x; this.y = y; } } class ColorPoint extends Point { constructor(x, y , color) { this.color = color; //報錯 super(x, y); this.color = color; //正確 } }super關鍵字 用作函數
super既可以當作函數使用,也可以當作對象使用。第一種情況,super作為函數調用時代表父類的構造函數。但是返回的之類的實例,即super內部的this指向實例。因此super()相當于A.prototype.constructor.call(this)。
class A { constructor() { console.log(new.target.name); } } class B extends A { constructor() { super(); //作為函數時只能在子類的構造函數中 } } new A // A new B // B作為對象
第二種情況,super作為對象時在在普通方法中指向父類的原型對象;在靜態方法中指向父類。
class A { p() { return 2; } } class B extends A { constructor() { super(); console.log(super.p()); // 2 這里相當于A.prototype.p() } } let b = new B();this指向
ES6規定,通過super調用父類的方法時,super會綁定子類的this。如果通過super對某個屬性賦值,這時的super就是this,賦值的屬性會變成子類實例的屬性。
class A { constructor() { this.x = 1; } print() { console.log(this.x); } } class B extends A { constructor() { super(); this.x = 2; super.x = 3; } m() { super.print(); } } let b = new B(); b.m() // 3
ps ...參考資料《ES6標準入門》(第三版)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/104362.html
摘要:前言在理想的狀態下,你可以在深入了解之前了解和開發的所有知識。繼承另一個類的類,通常稱為類或類,而正在擴展的類稱為類或類。這種類型的組件稱為無狀態功能組件。在你有足夠的信心構建用戶界面之后,最好學習。 原文地址:JavaScript Basics Before You Learn React 原文作者: Nathan Sebhastian 寫在前面 為了不浪費大家的寶貴時間,在開...
摘要:但是,的本質仍然是函數,是構造函數的另外一種寫法。報錯原生構造函數的繼承對于一些原生的構造函數,比如,,,等,在是無法通過方法實現原生函數的內部屬性,原生函數內部的無法綁定,內部屬性獲得不了。 在沒有學習 ES6 之前,學習 React,真的是一件非常痛苦的事情。即使之前你對 ES5 有著很好的基礎,包括閉包、函數、原型鏈和繼承,但是 React 中已經普遍使用 ES6 的語法,包括 ...
摘要:在繼承的構造函數中,我們必須如上面的例子那么調用一次方法,它表示構造函數的繼承,與中利用繼承構造函數是一樣的功能。 showImg(https://segmentfault.com/img/remote/1460000009078532); 在實際開發中,ES6已經非常普及了。掌握ES6的知識變成了一種必須。盡管我們在使用時仍然需要經過babel編譯。 ES6徹底改變了前端的編碼風格,...
書籍完整目錄 4.1 react 代碼規范 showImg(https://segmentfault.com/img/bVyE9m); 關于 基礎規范 組件結構 命名規范 jsx 書寫規范 eslint-plugin-react 關于 在代碼的設計上,每個團隊可能都有一定的代碼規范和模式,好的代碼規范能夠提高代碼的可讀性便于協作溝通,好的模式能夠上層設計上避免不必要的 bug 出現。本節會參考...
閱讀 2950·2021-11-23 09:51
閱讀 3776·2021-11-22 15:29
閱讀 3226·2021-10-08 10:05
閱讀 1552·2021-09-22 15:20
閱讀 952·2019-08-30 15:56
閱讀 1069·2019-08-30 15:54
閱讀 732·2019-08-26 11:54
閱讀 2635·2019-08-26 11:32