日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

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

新聞中心

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

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

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

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

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

一、“class” 語(yǔ)法

基本語(yǔ)法是:

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

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

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

例如:

 
 
 
  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(); 

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

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

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

類(lèi)的方法之間沒(méi)有逗號(hào)

對(duì)于新手開(kāi)發(fā)人員來(lái)說(shuō),常見(jiàn)的陷阱是在類(lèi)的方法之間放置逗號(hào),這會(huì)導(dǎo)致語(yǔ)法錯(cuò)誤。

不要把這里的符號(hào)與對(duì)象字面量相混淆。在類(lèi)中,不需要逗號(hào)。

二、什么是 class?

所以,class 到底是什么?正如人們可能認(rèn)為的那樣,這不是一個(gè)全新的語(yǔ)言級(jí)實(shí)體。

讓我們揭開(kāi)其神秘面紗,看看類(lèi)究竟是什么。這將有助于我們理解許多復(fù)雜的方面。

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

看看下面這段代碼:

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

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

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

當(dāng) new User 對(duì)象被創(chuàng)建后,當(dāng)我們調(diào)用其方法時(shí),它會(huì)從原型中獲取對(duì)應(yīng)的方法,正如我們?cè)?F.prototype 一章中所講的那樣。因此,對(duì)象 new User 可以訪(fǎng)問(wèn)類(lèi)中的方法。

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

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

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

 三、不僅僅是語(yǔ)法糖

人們常說(shuō) class 是一個(gè)語(yǔ)法糖(旨在使內(nèi)容更易閱讀,但不引入任何新內(nèi)容的語(yǔ)法),因?yàn)槲覀儗?shí)際上可以在沒(méi)有 class 的情況下聲明相同的內(nèi)容:

 
 
 
  1. // 用純函數(shù)重寫(xiě) class User 
  2.  
  3. // 1. 創(chuàng)建構(gòu)造器函數(shù) 
  4. function User(name) { 
  5.   this.name = name; 
  6. // 函數(shù)的原型(prototype)默認(rèn)具有 "constructor" 屬性, 
  7. // 所以,我們不需要?jiǎng)?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(); 

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

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

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

此外,class 語(yǔ)法還帶來(lái)了許多其他功能,我們稍后將會(huì)探索它們。

四、類(lèi)表達(dá)式

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

這是一個(gè)類(lèi)表達(dá)式的例子:

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

 類(lèi)似于命名函數(shù)表達(dá)式(Named Function Expressions),類(lèi)表達(dá)式可能也應(yīng)該有一個(gè)名字。

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

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

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

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

 五、Getters/setters

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

這是一個(gè)使用 get/set 實(shí)現(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ù)上來(lái)講,這樣的類(lèi)聲明可以通過(guò)在 User.prototype 中創(chuàng)建 getters 和 setters 來(lái)實(shí)現(xiàn)。

六、計(jì)算屬性名稱(chēng) […]

這里有一個(gè)使用中括號(hào) [...] 的計(jì)算方法名稱(chēng)示例:

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

 這種特性很容易記住,因?yàn)樗鼈兒蛯?duì)象字面量類(lèi)似。

七、Class 字段

舊的瀏覽器可能需要 polyfill

類(lèi)字段(field)是最近才添加到語(yǔ)言中的。

之前,我們的類(lèi)僅具有方法。

“類(lèi)字段”是一種允許添加任何屬性的語(yǔ)法。

例如,讓我們?cè)?class User 中添加一個(gè) name 屬性:

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

 所以,我們就只需在表達(dá)式中寫(xiě) " = ",就這樣。

類(lèi)字段重要的不同之處在于,它們會(huì)在每個(gè)獨(dú)立對(duì)象中被設(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í)使用更復(fù)雜的表達(dá)式和函數(shù)調(diào)用:

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

 八、使用類(lèi)字段制作綁定方法

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

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

例如,此代碼將顯示 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 

 這個(gè)問(wèn)題被稱(chēng)為“丟失 this”。

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

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

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

 
 
 
  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 

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

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

九、總結(jié)

基本的類(lèi)語(yǔ)法看起來(lái)像這樣:

 
 
 
  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]() {} // 有計(jì)算名稱(chēng)(computed name)的方法(此處為 symbol) 
  14.   // ... 

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


文章題目:一篇帶給你JavaScript的Class語(yǔ)法介紹
網(wǎng)址分享:http://m.5511xx.com/article/cdodehi.html