日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
一篇帶給你JavaScript的Class語法介紹
  •  在面向?qū)ο蟮木幊讨?,class 是用于創(chuàng)建對象的可擴展的程序代碼模版,它為對象提供了狀態(tài)(成員變量)的初始值和行為(成員函數(shù)或方法)的實現(xiàn)。
  • Wikipedia

在日常開發(fā)中,我們經(jīng)常需要創(chuàng)建許多相同類型的對象,例如用戶(users)、商品(goods)或者任何其他東西。

成都創(chuàng)新互聯(lián)公司專注于企業(yè)網(wǎng)絡(luò)營銷推廣、網(wǎng)站重做改版、易門網(wǎng)站定制設(shè)計、自適應品牌網(wǎng)站建設(shè)、H5開發(fā)、商城系統(tǒng)網(wǎng)站開發(fā)、集團公司官網(wǎng)建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為易門等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

正如我們在 構(gòu)造器和操作符 "new" 一章中已經(jīng)學到的,new function 可以幫助我們實現(xiàn)這種需求。

但在現(xiàn)代 JavaScript 中,還有一個更高級的“類(class)”構(gòu)造方式,它引入許多非常棒的新功能,這些功能對于面向?qū)ο缶幊毯苡杏谩?/p>

一、“class” 語法

基本語法是:

 
 
 
  1. class MyClass { 
  2.   // class 方法 
  3.   constructor() { ... } 
  4.   method1() { ... } 
  5.   method2() { ... } 
  6.   method3() { ... } 
  7.   ... 

 然后使用 new MyClass() 來創(chuàng)建具有上述列出的所有方法的新對象。

new 會自動調(diào)用 constructor() 方法,因此我們可以在 constructor() 中初始化對象。

例如:

 
 
 
  1. class User { 
  2.  
  3.   constructor(name) { 
  4.     this.name = name; 
  5.   } 
  6.  
  7.   sayHi() { 
  8.     alert(this.name); 
  9.   } 
  10.  
  11.  
  12. // 用法: 
  13. let user = new User("John"); 
  14. user.sayHi(); 

 當 new User("John") 被調(diào)用:

  1. 一個新對象被創(chuàng)建。
  2. constructor 使用給定的參數(shù)運行,并為其分配 this.name。

……然后我們就可以調(diào)用對象方法了,例如 user.sayHi。

類的方法之間沒有逗號

對于新手開發(fā)人員來說,常見的陷阱是在類的方法之間放置逗號,這會導致語法錯誤。

不要把這里的符號與對象字面量相混淆。在類中,不需要逗號。

二、什么是 class?

所以,class 到底是什么?正如人們可能認為的那樣,這不是一個全新的語言級實體。

讓我們揭開其神秘面紗,看看類究竟是什么。這將有助于我們理解許多復雜的方面。

在 JavaScript 中,類是一種函數(shù)。

看看下面這段代碼:

 
 
 
  1. class User { 
  2.   constructor(name) { this.name = name; } 
  3.   sayHi() { alert(this.name); } 
  4.  
  5. // 佐證:User 是一個函數(shù) 
  6. alert(typeof User); // function 

 class User {...} 構(gòu)造實際上做了如下的事兒:

  1. 創(chuàng)建一個名為 User 的函數(shù),該函數(shù)成為類聲明的結(jié)果。該函數(shù)的代碼來自于 constructor 方法(如果我們不編寫這種方法,那么它就被假定為空)。
  2. 存儲類中的方法,例如 User.prototype 中的 sayHi。

當 new User 對象被創(chuàng)建后,當我們調(diào)用其方法時,它會從原型中獲取對應的方法,正如我們在 F.prototype 一章中所講的那樣。因此,對象 new User 可以訪問類中的方法。

我們可以將 class User 聲明的結(jié)果解釋為:

下面這些代碼很好地解釋了它們:

 
 
 
  1. class User { 
  2.   constructor(name) { this.name = name; } 
  3.   sayHi() { alert(this.name); } 
  4.  
  5. // class 是一個函數(shù) 
  6. alert(typeof User); // function 
  7.  
  8. // ...或者,更確切地說,是 constructor 方法 
  9. alert(User === User.prototype.constructor); // true 
  10.  
  11. // 方法在 User.prototype 中,例如: 
  12. alert(User.prototype.sayHi); // alert(this.name); 
  13.  
  14. // 在原型中實際上有兩個方法 
  15. alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi 

 三、不僅僅是語法糖

人們常說 class 是一個語法糖(旨在使內(nèi)容更易閱讀,但不引入任何新內(nèi)容的語法),因為我們實際上可以在沒有 class 的情況下聲明相同的內(nèi)容:

 
 
 
  1. // 用純函數(shù)重寫 class User 
  2.  
  3. // 1. 創(chuàng)建構(gòu)造器函數(shù) 
  4. function User(name) { 
  5.   this.name = name; 
  6. // 函數(shù)的原型(prototype)默認具有 "constructor" 屬性, 
  7. // 所以,我們不需要創(chuàng)建它 
  8.  
  9. // 2. 將方法添加到原型 
  10. User.prototype.sayHi = function() { 
  11.   alert(this.name); 
  12. }; 
  13.  
  14. // 用法: 
  15. let user = new User("John"); 
  16. user.sayHi(); 

 這個定義的結(jié)果與使用類得到的結(jié)果基本相同。因此,這確實是將 class 視為一種定義構(gòu)造器及其原型方法的語法糖的理由。

盡管,它們之間存在著重大差異:

  1. 首先,通過 class 創(chuàng)建的函數(shù)具有特殊的內(nèi)部屬性標記 [[FunctionKind]]:"classConstructor"。因此,它與手動創(chuàng)建并不完全相同。編程語言會在許多地方檢查該屬性。例如,與普通函數(shù)不同,必須使用 new 來調(diào)用它:class User { constructor() {} } alert(typeof User); // function User(); // Error: Class constructor User cannot be invoked without 'new'此外,大多數(shù) JavaScript 引擎中的類構(gòu)造器的字符串表示形式都以 “class…” 開頭class User {constructor() {} } alert(User); // class User { ... }還有其他的不同之處,我們很快就會看到。
  2. 類方法不可枚舉。 類定義將 "prototype" 中的所有方法的 enumerable 標志設(shè)置為 false。這很好,因為如果我們對一個對象調(diào)用 for..in 方法,我們通常不希望 class 方法出現(xiàn)。
  3. 類總是使用 use strict。 在類構(gòu)造中的所有代碼都將自動進入嚴格模式。

此外,class 語法還帶來了許多其他功能,我們稍后將會探索它們。

四、類表達式

就像函數(shù)一樣,類可以在另外一個表達式中被定義,被傳遞,被返回,被賦值等。

這是一個類表達式的例子:

 
 
 
  1. let User = class { 
  2.   sayHi() { 
  3.     alert("Hello"); 
  4.   } 
  5. }; 

 類似于命名函數(shù)表達式(Named Function Expressions),類表達式可能也應該有一個名字。

如果類表達式有名字,那么該名字僅在類內(nèi)部可見:

 
 
 
  1. // “命名類表達式(Named Class Expression)” 
  2. // (規(guī)范中沒有這樣的術(shù)語,但是它和命名函數(shù)表達式類似) 
  3. let User = class MyClass { 
  4.   sayHi() { 
  5.     alert(MyClass); // MyClass 這個名字僅在類內(nèi)部可見 
  6.   } 
  7. }; 
  8.  
  9. new User().sayHi(); // 正常運行,顯示 MyClass 中定義的內(nèi)容 
  10.  
  11. alert(MyClass); // error,MyClass 在外部不可見 

 我們甚至可以動態(tài)地“按需”創(chuàng)建類,就像這樣:

 
 
 
  1. function makeClass(phrase) { 
  2.   // 聲明一個類并返回它 
  3.   return class { 
  4.     sayHi() { 
  5.       alert(phrase); 
  6.     } 
  7.   }; 
  8.  
  9. // 創(chuàng)建一個新的類 
  10. let User = makeClass("Hello"); 
  11.  
  12. new User().sayHi(); // Hello 

 五、Getters/setters

就像對象字面量,類可能包括 getters/setters,計算屬性(computed properties)等。

這是一個使用 get/set 實現(xiàn) user.name 的示例:

 
 
 
  1. class User { 
  2.  
  3.   constructor(name) { 
  4.     // 調(diào)用 setter 
  5.     this.name = name; 
  6.   } 
  7.  
  8.   get name() { 
  9.     return this._name; 
  10.   } 
  11.  
  12.   set name(value) { 
  13.     if (value.length < 4) { 
  14.       alert("Name is too short."); 
  15.       return; 
  16.     } 
  17.     this._name = value; 
  18.   } 
  19.  
  20.  
  21. let user = new User("John"); 
  22. alert(user.name); // John 
  23.  
  24. user = new User(""); // Name is too short. 

 從技術(shù)上來講,這樣的類聲明可以通過在 User.prototype 中創(chuàng)建 getters 和 setters 來實現(xiàn)。

六、計算屬性名稱 […]

這里有一個使用中括號 [...] 的計算方法名稱示例:

 
 
 
  1. class User { 
  2.  
  3.   ['say' + 'Hi']() { 
  4.     alert("Hello"); 
  5.   } 
  6.  
  7.  
  8. new User().sayHi(); 

 這種特性很容易記住,因為它們和對象字面量類似。

七、Class 字段

舊的瀏覽器可能需要 polyfill

類字段(field)是最近才添加到語言中的。

之前,我們的類僅具有方法。

“類字段”是一種允許添加任何屬性的語法。

例如,讓我們在 class User 中添加一個 name 屬性:

 
 
 
  1. class User { 
  2.   name = "John"; 
  3.  
  4.   sayHi() { 
  5.     alert(`Hello, ${this.name}!`); 
  6.   } 
  7.  
  8. new User().sayHi(); // Hello, John! 

 所以,我們就只需在表達式中寫 " = ",就這樣。

類字段重要的不同之處在于,它們會在每個獨立對象中被設(shè)好,而不是設(shè)在 User.prototype:

 
 
 
  1. class User { 
  2.   name = "John"; 
  3.  
  4. let user = new User(); 
  5. alert(user.name); // John 
  6. alert(User.prototype.name); // undefined 

 我們也可以在賦值時使用更復雜的表達式和函數(shù)調(diào)用:

 
 
 
  1. class User { 
  2.   name = prompt("Name, please?", "John"); 
  3.  
  4. let user = new User(); 
  5. alert(user.name); // John 

 八、使用類字段制作綁定方法

正如 函數(shù)綁定 一章中所講的,JavaScript 中的函數(shù)具有動態(tài)的 this。它取決于調(diào)用上下文。

因此,如果一個對象方法被傳遞到某處,或者在另一個上下文中被調(diào)用,則 this 將不再是對其對象的引用。

例如,此代碼將顯示 undefined:

 
 
 
  1. class Button { 
  2.   constructor(value) { 
  3.     this.value = value; 
  4.   } 
  5.  
  6.   click() { 
  7.     alert(this.value); 
  8.   } 
  9.  
  10. let button = new Button("hello"); 
  11.  
  12. setTimeout(button.click, 1000); // undefined 

 這個問題被稱為“丟失 this”。

我們在 函數(shù)綁定 一章中講過,有兩種可以修復它的方式:

  1. 傳遞一個包裝函數(shù),例如 setTimeout(() => button.click(), 1000)。
  2. 將方法綁定到對象,例如在 constructor 中。

類字段提供了另一種非常優(yōu)雅的語法:

 
 
 
  1. class Button { 
  2.   constructor(value) { 
  3.     this.value = value; 
  4.   } 
  5.   click = () => { 
  6.     alert(this.value); 
  7.   } 
  8.  
  9. let button = new Button("hello"); 
  10.  
  11. setTimeout(button.click, 1000); // hello 

 類字段 click = () => {...} 是基于每一個對象被創(chuàng)建的,在這里對于每一個 Button 對象都有一個獨立的方法,在內(nèi)部都有一個指向此對象的 this。我們可以把 button.click 傳遞到任何地方,而且 this 的值總是正確的。

在瀏覽器環(huán)境中,它對于進行事件監(jiān)聽尤為有用。

九、總結(jié)

基本的類語法看起來像這樣:

 
 
 
  1. class MyClass { 
  2.   prop = value; // 屬性 
  3.  
  4.   constructor(...) { // 構(gòu)造器 
  5.     // ... 
  6.   } 
  7.  
  8.   method(...) {} // method 
  9.  
  10.   get something(...) {} // getter 方法 
  11.   set something(...) {} // setter 方法 
  12.  
  13.   [Symbol.iterator]() {} // 有計算名稱(computed name)的方法(此處為 symbol) 
  14.   // ... 

 技術(shù)上來說,MyClass 是一個函數(shù)(我們提供作為 constructor 的那個),而 methods、getters 和 settors 都被寫入了 MyClass.prototype。


新聞名稱:一篇帶給你JavaScript的Class語法介紹
鏈接分享:http://www.dlmjj.cn/article/cdodehi.html