From 218934fa2ed1c702a6d3923d2aa2cc6b43c48684 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:43:23 -0500 Subject: initial commit --- .../reference/classes/constructor/index.html | 157 +++++++++ .../reference/classes/extends/index.html | 108 ++++++ .../web/javascript/reference/classes/index.html | 362 +++++++++++++++++++++ .../javascript/reference/classes/static/index.html | 123 +++++++ 4 files changed, 750 insertions(+) create mode 100644 files/zh-tw/web/javascript/reference/classes/constructor/index.html create mode 100644 files/zh-tw/web/javascript/reference/classes/extends/index.html create mode 100644 files/zh-tw/web/javascript/reference/classes/index.html create mode 100644 files/zh-tw/web/javascript/reference/classes/static/index.html (limited to 'files/zh-tw/web/javascript/reference/classes') diff --git a/files/zh-tw/web/javascript/reference/classes/constructor/index.html b/files/zh-tw/web/javascript/reference/classes/constructor/index.html new file mode 100644 index 0000000000..8da81e9b71 --- /dev/null +++ b/files/zh-tw/web/javascript/reference/classes/constructor/index.html @@ -0,0 +1,157 @@ +--- +title: 建構子 +slug: Web/JavaScript/Reference/Classes/constructor +translation_of: Web/JavaScript/Reference/Classes/constructor +--- +
{{jsSidebar("Classes")}}
+ +

constructor(建構子)是個隨著 class 一同建立並初始化物件的特殊方法。

+ +

語法

+ +
constructor([arguments]) { ... }
+ +

敘述

+ +

一個 class 只能有一個稱為 constructor 的特殊物件。如果一個 class 出現兩次以上的 constructor,就會發生 {{jsxref("SyntaxError")}} 錯誤。

+ +

如果不指定建構子,就會使用預設的建構子。

+ +

示例

+ +

使用 constructor 方法

+ +

這段程式碼是從 classes sample 擷取而來。(線上範例

+ +
class Square extends Polygon {
+  constructor(length) {
+    // 我們在這裡呼叫了 class 的建構子提供多邊形的長寬值
+    super(length, length);
+    // 注意:在 derived class 中,super() 必須在使用 this 以前被呼叫。不這樣的話會發生錯誤。
+    this.name = 'Square';
+  }
+
+  get area() {
+    return this.height * this.width;
+  }
+
+  set area(value) {
+    this.area = value;
+  }
+}
+ +

預設的建構子

+ +

如上文所說:如果不指定建構子,就會使用預設的建構子。對 base classes 而言,預設的建構子長得像這樣:

+ +
constructor() {}
+
+ +

對 derived class 而言,預設的建構子長得像這樣:

+ +
constructor(...args) {
+  super(...args);
+}
+ +

規範

+ + + + + + + + + + + + + + + + + + + +
規範狀態註解
{{SpecName('ES2015', '#sec-static-semantics-constructormethod', 'Constructor Method')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-static-semantics-constructormethod', 'Constructor Method')}}{{Spec2('ESDraft')}}
+ +

瀏覽器相容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
功能ChromeFirefox (Gecko)Internet ExplorerOperaSafari
基本支援{{CompatChrome(42.0)}}{{CompatGeckoDesktop(45)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
預設的建構子{{CompatUnknown}}{{CompatGeckoDesktop(45)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
功能AndroidAndroid WebviewFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
基本支援{{CompatNo}}{{CompatChrome(42.0)}}{{CompatGeckoMobile(45)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(42.0)}}
預設的建構子{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile(45)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

參見

+ + diff --git a/files/zh-tw/web/javascript/reference/classes/extends/index.html b/files/zh-tw/web/javascript/reference/classes/extends/index.html new file mode 100644 index 0000000000..ce729e552b --- /dev/null +++ b/files/zh-tw/web/javascript/reference/classes/extends/index.html @@ -0,0 +1,108 @@ +--- +title: extends +slug: Web/JavaScript/Reference/Classes/extends +translation_of: Web/JavaScript/Reference/Classes/extends +--- +
{{jsSidebar("Classes")}}
+ +

extends 關鍵字被使用於類別(class)宣告類別(class)表達式中來建立擴展的子類別 。

+ +
{{EmbedInteractiveExample("pages/js/classes-extends.html", "taller")}}
+ + + +

語法

+ +
class ChildClass extends ParentClass { ... }
+
+ +

解釋

+ +

extends 關鍵字可用於建立一個自訂類別或內建類別的子類別。

+ +

其繼承之原型 .prototype 必須是 {{jsxref("Object")}} 或 {{jsxref("null")}}。

+ +

範例

+ +

使用 extends

+ +

第一個範例是根據 Polygon類別建立一個名為 Square 的子類別。此範例提取自線上示例

+ +
class Square extends Polygon {
+  constructor(length) {
+    // Here, it calls the parent class' constructor with lengths
+    // provided for the Polygon's width and height
+    super(length, length);
+    // Note: In derived classes, super() must be called before you
+    // can use 'this'. Leaving this out will cause a reference error.
+    this.name = 'Square';
+  }
+
+  get area() {
+    return this.height * this.width;
+  }
+}
+ +

使用 extends 於內建類別

+ +

這個範例擴展了內建的 {{jsxref("Date")}} 類別。此範例提取自線上範例

+ +
class myDate extends Date {
+  constructor() {
+    super();
+  }
+
+  getFormattedDate() {
+    var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
+    return this.getDate() + '-' + months[this.getMonth()] + '-' + this.getFullYear();
+  }
+}
+ +

擴展 null

+ +

像擴展普通類別一樣擴展 {{jsxref("null")}},但新對象的原型不會繼承 {{jsxref("Object.prototype")}}。

+ +
class nullExtends extends null {
+  constructor() {}
+}
+
+Object.getPrototypeOf(nullExtends); // Function.prototype
+Object.getPrototypeOf(nullExtends.prototype) // null
+
+new nullExtends(); //ReferenceError: this is not defined
+
+ +

標準

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-class-definitions', 'extends')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-class-definitions', 'extends')}}{{Spec2('ESDraft')}} 
+ +

瀏覽器相容性

+ + + +

{{Compat("javascript.classes.extends")}}

+ +

參見

+ + diff --git a/files/zh-tw/web/javascript/reference/classes/index.html b/files/zh-tw/web/javascript/reference/classes/index.html new file mode 100644 index 0000000000..e3a62d781b --- /dev/null +++ b/files/zh-tw/web/javascript/reference/classes/index.html @@ -0,0 +1,362 @@ +--- +title: Classes +slug: Web/JavaScript/Reference/Classes +tags: + - Classes + - Constructors +translation_of: Web/JavaScript/Reference/Classes +--- +
{{JsSidebar("Classes")}}
+ +

ECMAScript 6 中引入了類別 (class) 作為 JavaScript 現有原型程式(prototype-based)繼承的語法糖。類別語法並不是要引入新的物件導向繼承模型到 JavaScript 中,而是提供一個更簡潔的語法來建立物件和處理繼承。

+ +

定義類別

+ +

類別實際上是一種特別的函數(functions),就跟你可以定義函數敘述和函數宣告一樣,類別的語法有兩個元件:類別敘述(class expressions)和類別宣告(class declarations)。

+ +

類別宣告

+ +

一個定義類別的方法是使用類別宣告(class declaration),要宣告一個類別,你要使用關鍵字 class 搭配類別名稱(此例為 "Polygon")。

+ +
class Polygon {
+  constructor(height, width) {
+    this.height = height;
+    this.width = width;
+  }
+}
+ +

Hoisting

+ +

函數宣告類別宣告的一個重要差別在於函數宣告是 {{Glossary("Hoisting", "hoisted")}} ,類別宣告則不是。 你需要先宣告你的類別,然後存取它,否則像是下面的程式碼就會丟出一個 {{jsxref("ReferenceError")}}:

+ +
var p = new Polygon(); // ReferenceError
+
+class Polygon {}
+
+ +

類別敘述

+ +

類別敘述是定義類別的另一種方法。類別敘述可以有名稱或是無名稱。賦予一個有名稱類別敘述的名稱只在類別主體(class's body)中有作用。(但是類別敘述的名稱可以透過該類別(不是實例)的 .name 屬性存取。)

+ +
// unnamed
+var Polygon = class {
+  constructor(height, width) {
+    this.height = height;
+    this.width = width;
+  }
+};
+
+// named
+var Polygon = class Polygon {
+  constructor(height, width) {
+    this.height = height;
+    this.width = width;
+  }
+};
+
+
+ +

注意:類別敘述跟上述提到的類別宣告一樣,都會受到hoisting的影響。

+ +

類別主體與方法定義

+ +

類別的主體指的是被大括號({})包含的部分,你可以在這裡面定義類別成員(members),例如方法(methods)或建構子(constructors)。

+ +

Strict mode

+ +

類別宣告類別敘述的主體都會以嚴格模式(strict mode)執行,也就是說,建構子、靜態方法和原型方法、getter及setter函數等都會以嚴格模式執行。

+ +

建構子

+ +

建構子(constructor)方法是一個特別的方法,用來建立和初始化一個類別的物件。一個類別只能有一個名為建構子(constructor)的特別方法。當類別中含有一個以上的建構子方法時,{{jsxref("SyntaxError")}} 將會被拋出。

+ +

一個建構子可以用關鍵字 super 來呼叫父類別的建構子。

+ +

原型方法

+ +

參見 method definitions

+ +
class Polygon {
+  constructor(height, width) {
+    this.height = height;
+    this.width = width;
+  }
+  // Getter
+  get area() {
+    return this.calcArea();
+  }
+  // Method
+  calcArea() {
+    return this.height * this.width;
+  }
+}
+
+const square = new Polygon(10, 10);
+
+console.log(square.area); //100
+ +

靜態方法(Static methods)

+ +

關鍵字 static 定義了一個類別的靜態方法,靜態方法不需要實體化它所屬類別的實例就可以被呼叫,它也無法被已實體化的類別物件呼叫。靜態方法經常被用來建立給應用程式使用的工具函數。

+ +
class Point {
+    constructor(x, y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    static distance(a, b) {
+        const dx = a.x - b.x;
+        const dy = a.y - b.y;
+
+        return Math.sqrt(dx*dx + dy*dy);
+    }
+}
+
+const p1 = new Point(5, 5);
+const p2 = new Point(10, 10);
+
+console.log(Point.distance(p1, p2)); // 7.0710678118654755
+
+ +

裝箱、原型方法及靜態方法

+ +

當一個靜態方法或原形方法被呼叫,但沒有一個物件的值與this綁定時,被呼叫的函數中this關鍵字會是undefined在此情況下,自動裝箱(autoboxing)不會發生。?即使我們在非嚴格模式中寫程式,此行為仍然會存在,這是因為所有的函式、定義方法、建構子、getters和setters都是在嚴格模式中執行。因此,若我們沒有定義this的值,this會是undefined

+ +
class Animal {
+  speak() {
+    return this;
+  }
+  static eat() {
+    return this;
+  }
+}
+
+let obj = new Animal();
+obj.speak(); // Animal {}
+let speak = obj.speak;
+speak(); // undefined
+
+Animal.eat() // class Animal
+let eat = Animal.eat;
+eat(); // undefined
+ +

若我們將上述程式用傳統的函式基礎類別(function based classes)表達,自動裝箱則會依據this在其被呼叫的函式中所綁定的值發生。

+ +
function Animal() { }
+
+Animal.prototype.speak = function() {
+  return this;
+}
+
+Animal.eat = function() {
+  return this;
+}
+
+let obj = new Animal();
+let speak = obj.speak;
+speak(); // 全域物件
+
+let eat = Animal.eat;
+eat(); // 全域物件
+ +

extends 建立子類別

+ +

關鍵字 extends 是在類別宣告或是類別敘述中建立子類別的方法。

+ +
class Animal {
+  constructor(name) {
+    this.name = name;
+  }
+
+  speak() {
+    console.log(this.name + ' makes a noise.');
+  }
+}
+
+class Dog extends Animal {
+  speak() {
+    console.log(this.name + ' barks.');
+  }
+}
+
+var d = new Dog('Mitzie');
+d.speak(); // Mitzie barks.
+
+ +

若在子類別中有建構子(constructor),要使用this前則必須先呼叫super()函式。

+ +

你也可以擴充(extends)傳統的函式基礎"類別"。

+ +
function Animal (name) {
+  this.name = name;
+}
+
+Animal.prototype.speak = function () {
+  console.log(this.name + ' makes a noise.');
+}
+
+class Dog extends Animal {
+  speak() {
+    console.log(this.name + ' barks.');
+  }
+}
+
+var d = new Dog('Mitzie');
+d.speak(); // Mitzie barks.
+ +

注意類別並無法擴充一般(non-constructible不可建構的)物件。如果您想要繼承自一般的物件,可以使用{{jsxref("Object.setPrototypeOf()")}}來達成。

+ +
var Animal = {
+  speak() {
+    console.log(this.name + ' makes a noise.');
+  }
+};
+
+class Dog {
+  constructor(name) {
+    this.name = name;
+  }
+}
+
+// 如果你沒有用以下的方法,當你呼叫speak時會出現TypeError
+Object.setPrototypeOf(Dog.prototype, Animal);
+
+var d = new Dog('Mitzie');
+d.speak(); // Mitzie makes a noise.
+ +

Species

+ +

你可能會希望在陣列的衍生類別 MyArray 中回傳陣列 ({{jsxref("Array")}}) ,Species 這個模式讓你能覆寫默認的建構子 (contructor)。

+ +

舉例來說,當你使用像 {{jsxref("Array.map", "map()")}} 這類會回傳默認建構子的方法時,你希望能回傳父物件 Array ,而不是 MyArray 物件。 {{jsxref("Symbol.species")}} 符號讓你做到這件事:

+ +
class MyArray extends Array {
+  // Overwrite species to the parent Array constructor
+  static get [Symbol.species]() { return Array; }
+}
+
+var a = new MyArray(1,2,3);
+var mapped = a.map(x => x * x);
+
+console.log(mapped instanceof MyArray); // false
+console.log(mapped instanceof Array);   // true
+ +

super 呼叫父類別

+ +

關鍵字 super 是用來提供一個類別呼叫其父類別的函數。

+ +
class Cat {
+  constructor(name) {
+    this.name = name;
+  }
+
+  speak() {
+    console.log(this.name + ' makes a noise.');
+  }
+}
+
+class Lion extends Cat {
+  speak() {
+    super.speak();
+    console.log(this.name + ' roars.');
+  }
+}
+
+var l = new Lion('Fuzzy');
+l.speak();
+// Fuzzy makes a noise.
+// Fuzzy roars.
+
+ +

ES5 繼承語法與 ES6 類別語法的比較

+ +

TBD

+ +

範例

+ +

TBD

+ +

規格

+ + + + + + + + + + + + + + +
規格狀態評論
{{SpecName('ES6', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES6')}}Initial definition.
+ +

瀏覽器相容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)EdgeInternet ExplorerOperaSafari
Basic support{{CompatChrome(42.0)}}[1]
+ {{CompatChrome(49.0)}}
{{CompatGeckoDesktop(45)}}13{{CompatNo}}{{CompatNo}}{{CompatSafari(9.0)}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatGeckoMobile(45)}}{{CompatUnknown}}{{CompatUnknown}}9{{CompatChrome(42.0)}}[1]
+ {{CompatChrome(49.0)}}
+
+ +

參見

+ + diff --git a/files/zh-tw/web/javascript/reference/classes/static/index.html b/files/zh-tw/web/javascript/reference/classes/static/index.html new file mode 100644 index 0000000000..49e18b44bb --- /dev/null +++ b/files/zh-tw/web/javascript/reference/classes/static/index.html @@ -0,0 +1,123 @@ +--- +title: static +slug: Web/JavaScript/Reference/Classes/static +translation_of: Web/JavaScript/Reference/Classes/static +--- +
{{jsSidebar("Classes")}}
+ +
使用關鍵字 static 來定義一個靜態的方法(method)給類別(class),靜態方法在由類別所建立的物件實體(instance)上不能被呼叫,取而代之的是,靜態方法只能由類別本身呼叫。他們通常作為工具函式(utility functions)使用。像是建立物件或複製物件的函式。
+ +
+ +

語法

+ +
static methodName() { ... }
+ +

敘述

+ +

靜態方法不須實例化(instantiating)其類別即可被呼叫,但當類別被實例化(instantiating)後則靜態方法不能被呼叫。 靜態方法常被使用在建立應用程式的工具函式(utility functions)。

+ +

範例

+ +

下面的範例示範了許多東西。他示範了如何在一個可以有子類別的類別中實作一個靜態方法。最後示範了靜態方法在什麼情形下正確與錯誤的呼叫。

+ +
class Triple {
+  static triple(n) {
+    n = n || 1; //should not be a bitwise operation
+    return n * 3;
+  }
+}
+
+class BiggerTriple extends Triple {
+  static triple(n) {
+    return super.triple(n) * super.triple(n);
+  }
+}
+
+console.log(Triple.triple());        // 3
+console.log(Triple.triple(6));       // 18
+console.log(BiggerTriple.triple(3)); // 81
+var tp = new Triple();
+console.log(tp.triple());             // 'tp.triple is not a function'.
+ +

規格

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ESDraft')}}
+ +

瀏覽器相容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome(42.0)}}{{CompatGeckoDesktop(45)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatGeckoMobile(45)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(42.0)}}
+
+ +

你可能會需要看看

+ + -- cgit v1.2.3-54-g00ecf