å¨é¢å对象çç¼ç¨ä¸ï¼class æ¯ç¨äºå建对象ç坿©å±çç¨åºä»£ç 模çï¼å®ä¸ºå¯¹è±¡æä¾äºç¶æï¼æååéï¼çåå§å¼åè¡ä¸ºï¼æå彿°ææ¹æ³ï¼çå®ç°ã
卿¥å¸¸å¼åä¸ï¼æä»¬ç»å¸¸éè¦å建许å¤ç¸åç±»åç对象ï¼ä¾å¦ç¨æ·ï¼usersï¼ãååï¼goodsï¼æè ä»»ä½å ¶ä»ä¸è¥¿ã
æ£å¦æä»¬å¨ æé å¨åæä½ç¬¦ "new" ä¸ç« ä¸å·²ç»å¦å°çï¼new function å¯ä»¥å¸®å©æä»¬å®ç°è¿ç§éæ±ã
ä½å¨ç°ä»£ JavaScript ä¸ï¼è¿æä¸ä¸ªæ´é«çº§çâç±»ï¼classï¼âæé æ¹å¼ï¼å®å¼å ¥è®¸å¤é常æ£çæ°åè½ï¼è¿äºåè½å¯¹äºé¢å对象ç¼ç¨å¾æç¨ã
âclassâ è¯æ³
åºæ¬è¯æ³æ¯ï¼
class MyClass {
// class æ¹æ³
constructor() { ... }
method1() { ... }
method2() { ... }
method3() { ... }
...
}
ç¶åä½¿ç¨ new MyClass() æ¥å建å
·æä¸è¿°ååºçæææ¹æ³çæ°å¯¹è±¡ã
new ä¼èªå¨è°ç¨ constructor() æ¹æ³ï¼å æ¤æä»¬å¯ä»¥å¨ constructor() ä¸åå§å对象ã
ä¾å¦ï¼
class User {
constructor(name) {
this.name = name;
}
sayHi() {
alert(this.name);
}
}
// ç¨æ³ï¼
let user = new User("John");
user.sayHi();
å½ new User("John") 被è°ç¨ï¼
- ä¸ä¸ªæ°å¯¹è±¡è¢«å建ã
constructor使ç¨ç»å®çåæ°è¿è¡ï¼å¹¶å°å ¶èµå¼ç»this.nameã
â¦â¦ç¶åæä»¬å°±å¯ä»¥è°ç¨å¯¹è±¡æ¹æ³äºï¼ä¾å¦ user.sayHiã
å¯¹äºæ°æå¼åäººåæ¥è¯´ï¼å¸¸è§çé·é±æ¯å¨ç±»çæ¹æ³ä¹é´æ¾ç½®éå·ï¼è¿ä¼å¯¼è´è¯æ³é误ã
ä¸è¦æè¿éç符å·ä¸å¯¹è±¡åé¢éç¸æ··æ·ãå¨ç±»ä¸ï¼ä¸éè¦éå·ã
ä»ä¹æ¯ classï¼
æä»¥ï¼class å°åºæ¯ä»ä¹ï¼æ£å¦äººä»¬å¯è½è®¤ä¸ºç飿 ·ï¼è¿ä¸æ¯ä¸ä¸ªå
¨æ°çè¯è¨çº§å®ä½ã
让æä»¬æå¼å ¶ç¥ç§é¢çº±ï¼ççç±»ç©¶ç«æ¯ä»ä¹ãè¿å°æå©äºæä»¬ç解许å¤å¤æçæ¹é¢ã
å¨ JavaScript ä¸ï¼ç±»æ¯ä¸ç§å½æ°ã
ççä¸é¢è¿æ®µä»£ç ï¼
class User {
constructor(name) { this.name = name; }
sayHi() { alert(this.name); }
}
// ä½è¯ï¼User æ¯ä¸ä¸ªå½æ°
alert(typeof User); // function
class User {...} æé å®é
ä¸åäºå¦ä¸çäºå¿ï¼
- å建ä¸ä¸ªå为
Userç彿°ï¼è¯¥å½æ°æä¸ºç±»å£°æçç»æãè¯¥å½æ°çä»£ç æ¥èªäºconstructoræ¹æ³ï¼å¦ææä»¬ä¸ç¼åè¿ç§æ¹æ³ï¼é£ä¹å®å°±è¢«åå®ä¸ºç©ºï¼ã - åå¨ç±»ä¸çæ¹æ³ï¼ä¾å¦
User.prototypeä¸çsayHiã
å½ new User 对象被å建åï¼å½æä»¬è°ç¨å
¶æ¹æ³æ¶ï¼å®ä¼ä»ååä¸è·å对åºçæ¹æ³ï¼æ£å¦æä»¬å¨ F.prototype ä¸ç« ä¸æè®²ç飿 ·ãå æ¤ï¼å¯¹è±¡ new User å¯ä»¥è®¿é®ç±»ä¸çæ¹æ³ã
æä»¬å¯ä»¥å° class User 声æçç»æè§£é为ï¼
ä¸é¢è¿äºä»£ç å¾å¥½å°è§£éäºå®ä»¬ï¼
class User {
constructor(name) { this.name = name; }
sayHi() { alert(this.name); }
}
// class æ¯ä¸ä¸ªå½æ°
alert(typeof User); // function
// ...æè
ï¼æ´ç¡®åå°è¯´ï¼æ¯ constructor æ¹æ³
alert(User === User.prototype.constructor); // true
// æ¹æ³å¨ User.prototype ä¸ï¼ä¾å¦ï¼
alert(User.prototype.sayHi); // sayHi æ¹æ³ç代ç
// å¨ååä¸å®é
ä¸æä¸¤ä¸ªæ¹æ³
alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
ä¸ä» ä» æ¯è¯æ³ç³
人们常说 class æ¯ä¸ä¸ªè¯æ³ç³ï¼æ¨å¨ä½¿å
å®¹æ´æé
读ï¼ä½ä¸å¼å
¥ä»»ä½æ°å
容çè¯æ³ï¼ï¼å 为æä»¬å®é
ä¸å¯ä»¥å¨ä¸ä½¿ç¨ class çæ
åµä¸å£°æç¸åçå
容ï¼
// ç¨çº¯å½æ°éå class User
// 1. å建æé å¨å½æ°
function User(name) {
this.name = name;
}
// 彿°çååï¼prototypeï¼é»è®¤å
·æ "constructor" 屿§ï¼
// æä»¥ï¼æä»¬ä¸éè¦å建å®
// 2. å°æ¹æ³æ·»å å°åå
User.prototype.sayHi = function() {
alert(this.name);
};
// ç¨æ³ï¼
let user = new User("John");
user.sayHi();
è¿ä¸ªå®ä¹çç»æä¸ä½¿ç¨ç±»å¾å°çç»æåºæ¬ç¸åãå æ¤ï¼è¿ç¡®å®æ¯å° class è§ä¸ºä¸ç§å®ä¹æé å¨åå
¶ååæ¹æ³çè¯æ³ç³ççç±ã
尽管ï¼å®ä»¬ä¹é´åå¨çé大差å¼ï¼
-
é¦å ï¼éè¿
classå建ç彿°å ·æç¹æ®çå é¨å±æ§æ è®°[[IsClassConstructor]]: trueãå æ¤ï¼å®ä¸æå¨å建并ä¸å®å ¨ç¸åãç¼ç¨è¯è¨ä¼å¨è®¸å¤å°æ¹æ£æ¥è¯¥å±æ§ãä¾å¦ï¼ä¸æ®é彿°ä¸åï¼å¿ 须使ç¨
newæ¥è°ç¨å®ï¼class User { constructor() {} } alert(typeof User); // function User(); // Error: Class constructor User cannot be invoked without 'new'æ¤å¤ï¼å¤§å¤æ° JavaScript 弿ä¸çç±»æé å¨çå符串表示形å¼é½ä»¥ âclassâ¦â å¼å¤´
class User { constructor() {} } alert(User); // class User { ... }è¿æå ¶ä»çä¸åä¹å¤ï¼æä»¬å¾å¿«å°±ä¼çå°ã
-
ç±»æ¹æ³ä¸å¯æä¸¾ã ç±»å®ä¹å°
"prototype"ä¸çæææ¹æ³çenumerableæ å¿è®¾ç½®ä¸ºfalseãè¿å¾å¥½ï¼å ä¸ºå¦ææä»¬å¯¹ä¸ä¸ªå¯¹è±¡è°ç¨
for..inæ¹æ³ï¼æä»¬é常ä¸å¸æ class æ¹æ³åºç°ã -
ç±»æ»æ¯ä½¿ç¨
use strictã å¨ç±»æé ä¸çææä»£ç é½å°èªå¨è¿å ¥ä¸¥æ ¼æ¨¡å¼ã
æ¤å¤ï¼class è¯æ³è¿å¸¦æ¥äºè®¸å¤å
¶ä»åè½ï¼æä»¬ç¨åå°ä¼æ¢ç´¢å®ä»¬ã
类表达å¼
å°±å彿°ä¸æ ·ï¼ç±»å¯ä»¥å¨å¦å¤ä¸ä¸ªè¡¨è¾¾å¼ä¸è¢«å®ä¹ï¼è¢«ä¼ éï¼è¢«è¿åï¼è¢«èµå¼çã
è¿æ¯ä¸ä¸ªç±»è¡¨è¾¾å¼çä¾åï¼
let User = class {
sayHi() {
alert("Hello");
}
};
类似äºå½å彿°è¡¨è¾¾å¼ï¼Named Function Expressionsï¼ï¼ç±»è¡¨è¾¾å¼å¯è½ä¹åºè¯¥æä¸ä¸ªååã
å¦æç±»è¡¨è¾¾å¼æååï¼é£ä¹è¯¥ååä» å¨ç±»å é¨å¯è§ï¼
// âå½å类表达å¼ï¼Named Class Expressionï¼â
// (è§è䏿²¡æè¿æ ·çæ¯è¯ï¼ä½æ¯å®åå½å彿°è¡¨è¾¾å¼ç±»ä¼¼)
let User = class MyClass {
sayHi() {
alert(MyClass); // MyClass è¿ä¸ªååä»
å¨ç±»å
é¨å¯è§
}
};
new User().sayHi(); // æ£å¸¸è¿è¡ï¼æ¾ç¤º MyClass ä¸å®ä¹çå
容
alert(MyClass); // errorï¼MyClass å¨å¤é¨ä¸å¯è§
æä»¬çè³å¯ä»¥å¨æå°âæéâå建类ï¼å°±åè¿æ ·ï¼
function makeClass(phrase) {
// 声æä¸ä¸ªç±»å¹¶è¿åå®
return class {
sayHi() {
alert(phrase);
}
};
}
// å建ä¸ä¸ªæ°çç±»
let User = makeClass("Hello");
new User().sayHi(); // Hello
Getters/setters
å°±å对象åé¢éï¼ç±»å¯è½å æ¬ getters/settersï¼è®¡ç®å±æ§ï¼computed propertiesï¼çã
è¿æ¯ä¸ä¸ªä½¿ç¨ get/set å®ç° user.name ç示ä¾ï¼
class User {
constructor(name) {
// è°ç¨ setter
this.name = name;
}
get name() {
return this._name;
}
set name(value) {
if (value.length < 4) {
alert("Name is too short.");
return;
}
this._name = value;
}
}
let user = new User("John");
alert(user.name); // John
user = new User(""); // Name is too short.
仿æ¯ä¸æ¥è®²ï¼è¿æ ·ç类声æå¯ä»¥éè¿å¨ User.prototype ä¸å建 getters å setters æ¥å®ç°ã
计ç®å±æ§åç§° [â¦]
è¿éæä¸ä¸ªä½¿ç¨ä¸æ¬å· [...] çè®¡ç®æ¹æ³å称示ä¾ï¼
class User {
['say' + 'Hi']() {
alert("Hello");
}
}
new User().sayHi();
è¿ç§ç¹æ§å¾å®¹æè®°ä½ï¼å 为å®ä»¬å对象åé¢é类似ã
Class åæ®µ
ç±»åæ®µï¼fieldï¼æ¯æè¿ææ·»å å°è¯è¨ä¸çã
ä¹åï¼æä»¬çç±»ä» å ·ææ¹æ³ã
âç±»åæ®µâæ¯ä¸ç§å 许添å ä»»ä½å±æ§çè¯æ³ã
ä¾å¦ï¼è®©æä»¬å¨ class User 䏿·»å ä¸ä¸ª name 屿§ï¼
class User {
name = "John";
sayHi() {
alert(`Hello, ${this.name}!`);
}
}
new User().sayHi(); // Hello, John!
æä»¥ï¼æä»¬å°±åªéå¨è¡¨è¾¾å¼ä¸å â
ç±»åæ®µçéè¦åºå«å¨äºï¼å®ä»¬ä¼è¢«æå¨å®ä¾å¯¹è±¡ä¸ï¼èé User.prototype ä¸ï¼
class User {
name = "John";
}
let user = new User();
alert(user.name); // John
alert(User.prototype.name); // undefined
æä»¬ä¹å¯ä»¥å¨èµå¼æ¶ä½¿ç¨æ´å¤æç表达å¼å彿°è°ç¨ï¼
class User {
name = prompt("Name, please?", "John");
}
let user = new User();
alert(user.name); // John
使ç¨ç±»å段å¶ä½ç»å®æ¹æ³
æ£å¦ 彿°ç»å® ä¸ç« ä¸æè®²çï¼JavaScript ä¸ç彿°å
·æå¨æç thisãå®åå³äºè°ç¨ä¸ä¸æã
å æ¤ï¼å¦æä¸ä¸ªå¯¹è±¡æ¹æ³è¢«ä¼ éå°æå¤ï¼æè
å¨å¦ä¸ä¸ªä¸ä¸æä¸è¢«è°ç¨ï¼å this å°ä¸åæ¯å¯¹å
¶å¯¹è±¡çå¼ç¨ã
ä¾å¦ï¼æ¤ä»£ç å°æ¾ç¤º undefinedï¼
class Button {
constructor(value) {
this.value = value;
}
click() {
alert(this.value);
}
}
let button = new Button("hello");
setTimeout(button.click, 1000); // undefined
è¿ä¸ªé®é¢è¢«ç§°ä¸ºâ丢失 thisâã
æä»¬å¨ 彿°ç»å® ä¸ç« ä¸è®²è¿ï¼æä¸¤ç§å¯ä»¥ä¿®å¤å®çæ¹å¼ï¼
- ä¼ éä¸ä¸ªå
è£
彿°ï¼ä¾å¦
setTimeout(() => button.click(), 1000)ã - å°æ¹æ³ç»å®å°å¯¹è±¡ï¼ä¾å¦å¨ constructor ä¸ã
ç±»åæ®µæä¾äºå¦ä¸ç§é常ä¼é çè¯æ³ï¼
class Button {
constructor(value) {
this.value = value;
}
click = () => {
alert(this.value);
}
}
let button = new Button("hello");
setTimeout(button.click, 1000); // hello
ç±»åæ®µ click = () => {...} æ¯åºäºæ¯ä¸ä¸ªå¯¹è±¡è¢«å建çï¼å¨è¿éå¯¹äºæ¯ä¸ä¸ª Button å¯¹è±¡é½æä¸ä¸ªç¬ç«çæ¹æ³ï¼å¨å
é¨é½æä¸ä¸ªæåæ¤å¯¹è±¡ç thisãæä»¬å¯ä»¥æ button.click ä¼ éå°ä»»ä½å°æ¹ï¼èä¸ this ç弿»æ¯æ£ç¡®çã
卿µè§å¨ç¯å¢ä¸ï¼å®å¯¹äºè¿è¡äºä»¶çå¬å°¤ä¸ºæç¨ã
æ»ç»
åºæ¬çç±»è¯æ³çèµ·æ¥åè¿æ ·ï¼
class MyClass {
prop = value; // 屿§
constructor(...) { // æé å¨
// ...
}
method(...) {} // method
get something(...) {} // getter æ¹æ³
set something(...) {} // setter æ¹æ³
[Symbol.iterator]() {} // æè®¡ç®åç§°ï¼computed nameï¼çæ¹æ³ï¼æ¤å¤ä¸º symbolï¼
// ...
}
ææ¯ä¸æ¥è¯´ï¼MyClass æ¯ä¸ä¸ªå½æ°ï¼æä»¬æä¾ä½ä¸º constructor çé£ä¸ªï¼ï¼è methodsãgetters å setters é½è¢«åå
¥äº MyClass.prototypeã
å¨ä¸ä¸ç« ï¼æä»¬å°ä¼è¿ä¸æ¥å¦ä¹ ç±»çç¸å ³ç¥è¯ï¼å æ¬ç»§æ¿åå ¶ä»åè½ã
è¯è®º
<code>æ ç¾æå ¥åªæå 个è¯ç代ç ï¼æå ¥å¤è¡ä»£ç å¯ä»¥ä½¿ç¨<pre>æ ç¾ï¼å¯¹äºè¶ è¿ 10 è¡ç代ç ï¼å»ºè®®ä½ ä½¿ç¨æ²ç®±ï¼plnkrï¼JSBinï¼codepenâ¦ï¼