Baseline Widely available
extends
å
³é®åç¨äºç±»å£°ææè
类表达å¼ä¸ï¼ä»¥å建ä¸ä¸ªç±»ï¼è¯¥ç±»æ¯å¦ä¸ä¸ªç±»çåç±»ã
class DateFormatter extends Date {
getFormattedDate() {
const months = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
];
return `${this.getDate()}-${months[this.getMonth()]}-${this.getFullYear()}`;
}
}
console.log(new DateFormatter("August 19, 1975 23:15:30").getFormattedDate());
// Expected output: "19-Aug-1975"
è¯æ³
class ChildClass extends ParentClass { /* ⦠*/ }
ParentClass
æ±å¼ä¸ºæé 彿°ï¼å
æ¬ç±»ï¼æ null
ç表达å¼ã
extends
å
³é®åç¨æ¥å建èªå®ä¹ç±»æè
å
置对象çåç±»ã
ä»»ä½å¯ä»¥ç¨ new
è°ç¨å¹¶å
·æ prototype
屿§çæé 彿°é½å¯ä»¥ä½ä¸ºåéçç¶ç±»çæé 彿°ãè¿ä¸¤ä¸ªæ¡ä»¶å¿
须忶æç«ââä¾å¦ï¼ç»å®å½æ°å Proxy
å¯ä»¥è¢«æé ï¼ä½å®ä»¬æ²¡æ prototype
屿§ï¼å æ¤ä¸è½è¢«åç±»åã
function OldStyleClass() {
this.someProperty = 1;
}
OldStyleClass.prototype.someMethod = function () {};
class ChildClass extends OldStyleClass {}
class ModernClass {
someProperty = 1;
someMethod() {}
}
class AnotherChildClass extends ModernClass {}
ParentClass
ç prototype
屿§å¿
é¡»æ¯ Object
æ null
ï¼ä½å¨å®è·µä¸å¾å°éè¦æ
å¿è¿ä¸ªé®é¢ï¼å 为é对象ç prototype
æ 论å¦ä½é½ä¸ä¼æç
§åºæçæ¹å¼è¿è¡ï¼new
è¿ç®ç¬¦ä¼å¿½ç¥å®ï¼ã
function ParentClass() {}
ParentClass.prototype = 3;
class ChildClass extends ParentClass {}
// Uncaught TypeError: Class extends value does not have valid prototype property 3
console.log(Object.getPrototypeOf(new ParentClass()));
// [Object: null prototype] {}
// å®é
ä¸å¹¶ä¸æ¯ä¸ä¸ªæ°åï¼
extends
为 ChildClass
å ChildClass.prototype
设置äºååã
ChildClass
çåå对象 ChildClass.prototype
çåå对象 ç¼ºå° extends
Function.prototype
Object.prototype
extends null
Function.prototype
null
extends ParentClass
ParentClass
ParentClass.prototype
class ParentClass {}
class ChildClass extends ParentClass {}
// å
许éæå±æ§çç»§æ¿
Object.getPrototypeOf(ChildClass) === ParentClass;
// å
许å®ä¾å±æ§çç»§æ¿
Object.getPrototypeOf(ChildClass.prototype) === ParentClass.prototype;
extend
çå³ä¾§ä¸ä¸å®æ¯æ è¯ç¬¦ãä½ å¯ä»¥ä½¿ç¨ä»»ä½æ±å¼ä¸ºæé 彿°ç表达å¼ãè¿é常æå©äºå建混å
¥ï¼mixinï¼ãextends
表达å¼ä¸ç this
弿¯å´ç»ç±»å®ä¹ç this
ï¼èå¼ç¨ç±»çåç§°ä¼å¯¼è´ ReferenceError
ï¼å ä¸ºç±»å°æªåå§åã卿¤è¡¨è¾¾å¼ä¸ï¼await
å yield
æé¢æå·¥ä½ã
class SomeClass extends class {
constructor() {
console.log("åºç±»");
}
} {
constructor() {
super();
console.log("æ´¾çç±»");
}
}
new SomeClass();
// åºç±»
// æ´¾çç±»
åºç±»å¯ä»¥ä»æé 彿°ä¸è¿åä»»ä½å
容ï¼èæ´¾çç±»å¿
é¡»è¿å对象æ undefined
ï¼å¦åå°æåº TypeError
ã
class ParentClass {
constructor() {
return 1;
}
}
console.log(new ParentClass()); // ParentClass {}
// è¿åå¼å°è¢«å¿½ç¥ï¼å 为å®ä¸æ¯ä¸ä¸ªå¯¹è±¡
// è¿ä¸å½æ°æé 彿°ä¸è´
class ChildClass extends ParentClass {
constructor() {
super();
return 1;
}
}
console.log(new ChildClass()); // TypeError: Derived constructors may only return object or undefined
妿ç¶ç±»æé 彿°è¿åä¸ä¸ªå¯¹è±¡ï¼åå¨è¿ä¸æ¥åå§åç±»åæ®µæ¶ï¼è¯¥å¯¹è±¡å°è¢«ç¨ä½æ´¾çç±»ç this
å¼ãè¿ç§æå·§è¢«ç§°ä¸ºâè¿åè¦çâï¼å®å
è®¸å¨æ å
³å¯¹è±¡ä¸å®ä¹æ´¾çç±»çåæ®µï¼å
æ¬ç§æå段ï¼ã
è¦åï¼ æ åå§åä¼ç®åçç«åºæ¯ï¼ä»¥åçæ¬è§èä¸çå 置类çåç±»åæºå¶è®¾è®¡è¿åº¦ï¼å¯¹æ§è½åå®å ¨æ§é æäºä¸å¯å¿½è§çå½±åãæ°çå ç½®æ¹æ³è¾å°èèåç±»ï¼å¼æå®ç°è æ£å¨ç ç©¶æ¯å¦è¦å 餿äºåç±»æºå¶ãå¨å¢å¼ºå 置类æ¶ï¼è¯·èè使ç¨ç»åèéç»§æ¿ã
ä¸é¢æ¯æ©å±ç±»æ¶å¯è½ä¼éå°çä¸äºé®é¢ï¼
Promise.resolve()
æ Array.from()
ï¼æ¶ï¼è¿åçå®ä¾å§ç»æ¯åç±»çå®ä¾ãPromise.prototype.then()
æ Array.prototype.map()
ï¼æ¶ï¼è¿åçå®ä¾å§ç»æ¯åç±»çå®ä¾ãPromise
çåç±»ï¼è¦ç then()
ä¼èªå¨å¯¼è´ catch()
çè¡ä¸ºåçååï¼æå¯¹äº Map
çåç±»ï¼è¦ç set()
ä¼èªå¨å¯¼è´ Map()
æé 彿°çè¡ä¸ºåçååãç¶èï¼è¦æ£ç¡®å°å®ç°ä¸è¿°ææï¼éè¦ä»åºä¸å°çåªåã
this
çå¼ï¼ä»¥è·åæé 彿°æ¥æé è¿åçå®ä¾ãè¿æå³ç [p1,p2,p3].map(Promise.resolve)
伿åºé误ï¼å 为 Promise.resolve
ä¸ç this
æ¯ undefined
ãè§£å³è¿ä¸ªé®é¢çæ¹æ³æ¯ï¼å¦æ this
䏿¯æé 彿°ï¼å°±åéå°åºç±»ï¼å°±å Array.from()
æåç飿 ·ï¼ä½è¿ä»ç¶æå³çåºç±»æ¯ç¹ä¾ãthis.constructor
以è·åæé 彿°ã使¯ï¼new this.constructor()
å¯è½ä¼ç ´åèæ§ç代ç ï¼å 为 constructor
屿§æ¯å¯ååå¯é
ç½®çï¼èä¸ä¸åä»»ä½ä¿æ¤ãå æ¤ï¼è®¸å¤å¤å¶çå
ç½®æ¹æ³é½ä½¿ç¨æé 彿°ç [Symbol.species]
屿§ï¼é»è®¤æ
åµä¸åªè¿å this
ï¼å³æé 彿°æ¬èº«ï¼ãç¶èï¼[Symbol.species]
å
许è¿è¡ä»»æä»£ç åå建任æç±»åçå®ä¾ï¼è¿å°±å¸¦æ¥äºå®å
¨é®é¢ï¼å¹¶ä½¿åç±»åè¯ä¹åå¾é叏夿ãMap()
æé 彿°ï¼é£ä¹å®å¿
é¡»ææ¾å°è°ç¨ set()
æ¹æ³ x 次ï¼èä¸ä»
ä»
æ¯å°å
ç´ å¤å¶å°å
é¨åå¨ãè¿äºé®é¢å¹¶éå 置类æç¬æã对äºä½ èªå·±çç±»ï¼ä½ ä¹å¯è½éè¦ååºåæ ·çå³å®ãä¸è¿ï¼å¯¹äºå 置类æ¥è¯´ï¼å¯ä¼åæ§åå®å ¨æ§æ¯æ´å¤§çé®é¢ãæ°çå ç½®æ¹æ³æ»æ¯æé åºç±»ï¼å¹¶å°½å¯è½å°å°è°ç¨èªå®ä¹æ¹æ³ãå¦æä½ æ³å¨å®ç°ä¸è¿°ææç忶坹å 置类è¿è¡åç±»åï¼ä½ éè¦éåææå·²å ·æé»è®¤è¡ä¸ºçæ¹æ³ãå¨åºç±»ä¸æ·»å 任使°æ¹æ³é½å¯è½ä¼ç ´ååç±»çè¯ä¹ï¼å 为è¿äºæ¹æ³æ¯é»è®¤ç»§æ¿çãå æ¤ï¼æ©å±å ç½®ç±»çæ´å¥½æ¹æ³æ¯ä½¿ç¨ç»åã
æå± nullextends null
设计ç¨äºè½»æ¾å建ä¸ç»§æ¿èª Object.prototype
ç对象ãç¶èï¼ç±äºå
³äºæ¯å¦åºå¨æé 彿°ä¸è°ç¨ super()
çå³å®å°æªç¡®å®ï¼å æ¤å¨å®è·µä¸ä¸å¯è½ä½¿ç¨ä»»ä½ä¸è¿å对象çæé 彿°å®ç°æ¥æé è¿æ ·çç±»ãTC39 å§å伿£å¨åªåéæ°å¯ç¨è¿ä¸ç¹æ§ã
new (class extends null {})();
// TypeError: Super constructor null of anonymous class is not a constructor
new (class extends null {
constructor() {}
})();
// ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
new (class extends null {
constructor() {
super();
}
})();
// TypeError: Super constructor null of anonymous class is not a constructor
ç¸åï¼ä½ éè¦ä»æé 彿°ä¸æç¡®è¿åä¸ä¸ªå®ä¾ã
class NullClass extends null {
constructor() {
// ä½¿ç¨ new.target å
许派çç±»å
·ææ£ç¡®çååé¾
return Object.create(new.target.prototype);
}
}
const proto = Object.getPrototypeOf;
console.log(proto(proto(new NullClass()))); // null
ç¤ºä¾ ä½¿ç¨ extends
第ä¸ä¸ªä¾åæ¯æ ¹æ®å为 Polygon
ç±»å建ä¸ä¸ªå为 Square
çç±»ãå½åç¤ºä¾æ¯ä»è¿ä¸ªå¨çº¿æ¼ç¤ºä¸æååºæ¥çï¼æºä»£ç ï¼ã
class Square extends Polygon {
constructor(length) {
// å¨è¿éï¼å®ä¼è°ç¨ç¶ç±»çæé 彿°ï¼å¹¶ä¸ºå¤è¾¹å½¢ç宽度åé«åº¦æä¾é¿åº¦
super(length, length);
// 卿´¾çç±»ä¸ï¼å¿
é¡»å
è°ç¨ super() æè½ç¨âthisâãçç¥è¿ä¸ç¹å°å¯¼è´å¼ç¨é误ã
this.name = "Square";
}
get area() {
return this.height * this.width;
}
}
æ©å±æ®é对象
ç±»ä¸è½æ©å±å¸¸è§ï¼ä¸å¯æé ï¼å¯¹è±¡ã妿æ³éè¿å¨ç»§æ¿å®ä¾ä¸ä½¿ç¨å¸¸è§å¯¹è±¡çææå±æ§æ¥ç»§æ¿è¯¥å¯¹è±¡ï¼å¯ä»¥ä½¿ç¨ Object.setPrototypeOf()
代æ¿ï¼
const Animal = {
speak() {
console.log(`${this.name} ååºäºåªé³`);
},
};
class Dog {
constructor(name) {
this.name = name;
}
}
Object.setPrototypeOf(Dog.prototype, Animal);
const d = new Dog("Mitzie");
d.speak(); // Mitzie ååºäºåªé³
æ©å±å
置对象
è¿ä¸ªç¤ºä¾ç»§æ¿äºå
ç½®ç Date
对象ãå½åç¤ºä¾æ¯ä»è¿ä¸ªå¨çº¿æ¼ç¤ºä¸æååºæ¥çï¼æºä»£ç ï¼ã
class MyDate extends Date {
getFormattedDate() {
const months = [
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
];
return `${this.getDate()}-${months[this.getMonth()]}-${this.getFullYear()}`;
}
}
æ©å± Object
ææ JavaScript 对象é»è®¤æ
åµä¸é½ç»§æ¿èª Object.prototype
ï¼å æ¤ä¹ä¸çï¼ç¼å extends Object
似乿¯å¤ä½çãä¸å®å
¨ä¸å extends
çå¯ä¸åºå«æ¯æé 彿°æ¬èº«ç»§æ¿äº Object
çéææ¹æ³ï¼ä¾å¦ Object.keys()
ãç¶èï¼ç±äºæ²¡æä»»ä½ Object
éææ¹æ³ä¼ä½¿ç¨ this
å¼ï¼å æ¤ç»§æ¿è¿äºéææ¹æ³ä»ç¶æ²¡æä»»ä½ä»·å¼ã
Object()
æé 彿°ç¹æ®å¤çäºåç±»åæ
åµã妿éè¿ super()
éå¼è°ç¨è¯¥æé 彿°ï¼å该æé 彿°å§ç»ä»¥ new.target.prototype
为åååå§åä¸ä¸ªæ°å¯¹è±¡ãä¼ éç» super()
çä»»ä½å¼é½å°è¢«å¿½ç¥ã
class C extends Object {
constructor(v) {
super(v);
}
}
console.log(new C(1) instanceof Number); // false
console.log(C.keys({ a: 1, b: 2 })); // [ 'a', 'b' ]
å°è¿ç§è¡ä¸ºä¸ä¸å¯¹åç±»è¿è¡ç¹æ®å¤ççèªå®ä¹å è£ å¨è¿è¡æ¯è¾ï¼
function MyObject(v) {
return new Object(v);
}
class D extends MyObject {
constructor(v) {
super(v);
}
}
console.log(new D(1) instanceof Number); // true
Species
ä½ å¯è½å¸æå¨æ´¾çæ°ç»ç±» MyArray
ä¸è¿å Array
对象ãSpecies 模å¼å¯è®©ä½ è¦çé»è®¤æé 彿°ã
ä¾å¦ï¼å¨ä½¿ç¨ Array.prototype.map()
çè¿åé»è®¤æé 彿°çæ¹æ³æ¶ï¼ä½ 叿è¿äºæ¹æ³è¿åçæ¯ç¶ Array
对象ï¼è䏿¯ MyArray
对象ãSymbol.species
符å·å¯è®©ä½ åå°è¿ä¸ç¹ï¼
class MyArray extends Array {
// å° Species è¦çå°ç¶ç±» Array çæé 彿°
static get [Symbol.species]() {
return Array;
}
}
const a = new MyArray(1, 2, 3);
const mapped = a.map((x) => x * x);
console.log(mapped instanceof MyArray); // false
console.log(mapped instanceof Array); // true
许å¤å ç½®å¤å¶æ¹æ³é½å®ç°äºè¿ä¸è¡ä¸ºãæå ³æ¤åè½ç注æäºé¡¹ï¼è¯·åé åç±»åå 置类讨论ã
æ··å ¥æ½è±¡åç±»ææ··å ¥æ¯ç±»ç模æ¿ãä¸ä¸ªç±»åªè½æä¸ä¸ªç¶ç±»ï¼å æ¤ä¸å¯è½ä»å·¥å ·ç±»çå¤éç»§æ¿ãåè½å¿ é¡»ç±è¶ ç±»æä¾ã
ä¸ä¸ªä»¥ç¶ç±»ä¸ºè¾å ¥ï¼ä»¥æ©å±è¯¥ç¶ç±»çå类为è¾åºç彿°å¯ä»¥ç¨æ¥å®ç°æ··å ¥ï¼
const calculatorMixin = (Base) =>
class extends Base {
calc() {}
};
const randomizerMixin = (Base) =>
class extends Base {
randomize() {}
};
使ç¨è¿äºæ··å ¥çç±»å¯ä»¥è¿æ ·ç¼åï¼
class Foo {}
class Bar extends calculatorMixin(randomizerMixin(Foo)) {}
é¿å
ç»§æ¿
å¨é¢å对象ç¼ç¨ä¸ï¼ç»§æ¿æ¯ä¸ç§é常强çè¦åå
³ç³»ã宿å³çåç±»é»è®¤ç»§æ¿åºç±»çææè¡ä¸ºï¼ä½è¿å¹¶ä¸æ»æ¯ä½ æ³è¦çãä¾å¦ï¼è¯·ç ReadOnlyMap
çå®ç°ï¼
class ReadOnlyMap extends Map {
set() {
throw new TypeError("A read-only map must be set at construction time.");
}
}
ç»æåç° ReadOnlyMap
æ æ³æé ï¼å 为 Map()
æé 彿°è°ç¨äºå®ä¾ç set()
æ¹æ³ã
const m = new ReadOnlyMap([["a", 1]]); // TypeError: A read-only map must be set at construction time.
æä»¬å¯ä»¥éè¿ä½¿ç¨ä¸ä¸ªç§ææ å¿æ¥æç¤ºæ¯å¦æ£å¨æé å®ä¾æ¥è§£å³è¿ä¸ªé®é¢ãç¶èï¼è¿ç§è®¾è®¡çä¸ä¸ªæ´éè¦çé®é¢æ¯ï¼å®ç ´åäºéæ°æ¿æ¢ååï¼è¯¥ååè§å®åç±»åºè¯¥å¯ä»¥æ¿æ¢å
¶è¶
ç±»ã妿彿°ææä½¿ç¨ä¸ä¸ª Map
对象ï¼é£ä¹å®ä¹åºè¯¥è½å¤ä½¿ç¨ä¸ä¸ª ReadOnlyMap
对象ï¼è¿å¨è¿éå°±ä¼è¢«æç ´ã
ç»§æ¿å¸¸å¸¸ä¼å¯¼è´åââæ¤åé®é¢ï¼å 为两ç§ç±»åè½ç¶æå¾å¤å ±åç¹å¾ï¼ä½é½ä¸è½å®ç¾å°å å«å¦ä¸ç§ç±»åçè¡ä¸ºãä¸è¬æ¥è¯´ï¼é¤éæé常å åççç±ä½¿ç¨ç»§æ¿ï¼å¦åæå¥½ä½¿ç¨ç»åãç»åæ¯æä¸ä¸ªç±»æ¥æå¦ä¸ä¸ªç±»å¯¹è±¡çå¼ç¨ï¼ä½åªå°è¯¥å¯¹è±¡ç¨ä½å®ç°ç»èã
class ReadOnlyMap {
#data;
constructor(values) {
this.#data = new Map(values);
}
get(key) {
return this.#data.get(key);
}
has(key) {
return this.#data.has(key);
}
get size() {
return this.#data.size;
}
*keys() {
yield* this.#data.keys();
}
*values() {
yield* this.#data.values();
}
*entries() {
yield* this.#data.entries();
}
*[Symbol.iterator]() {
yield* this.#data[Symbol.iterator]();
}
}
å¨è¿ç§æ
åµä¸ï¼ReadOnlyMap
ç±»ä¸æ¯ Map
çåç±»ï¼ä½å®ä»ç¶å®ç°äºå¤§é¨åç¸åçæ¹æ³ãè¿æå³çæ´å¤ç代ç éå¤ï¼ä½ä¹æå³ç ReadOnlyMap
ç±»ä¸ Map
ç±»ä¸æ¯å¼ºè¦åçï¼å¹¶ä¸å¨ Map
ç±»æ´æ¹æ¶ä¸ä¼è½»æä¸æï¼ä»èé¿å
äºåç±»åå
置类çè¯ä¹é®é¢ãä¾å¦ï¼å¦æ Map
类添å äºä¸ä¸ªä¸è°ç¨ set()
ç emplace()
æ¹æ³ï¼å°±ä¼å¯¼è´ ReadOnlyMap
ç±»ä¸åæ¯åªè¯»çï¼é¤éåè
ä¹ç¸åºå°æ´æ°ä»¥è¦ç emplace()
ãæ¤å¤ï¼ReadOnlyMap
å¯¹è±¡æ ¹æ¬æ²¡æ set
æ¹æ³ï¼è¿æ¯å¨è¿è¡æ¶æåºé误æ´åç¡®ã
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4