对象与原型
classes、prototypal inheritance、Symbol。
35 分钟
对象与原型
javascript-core 讲过对象字面量;本课深入 原型链、class 语法糖 与 Symbol。理解原型有助于调试 react-essentials 组件继承与 nodejs-essentials 内置类扩展。
学习目标
- 追踪
obj.method()的原型链查找过程 - 使用
class并理解其原型本质 - 用 Symbol 定义不会冲突的属性键
原型链
const animal = {
eat() { return 'eating'; },
};
const dog = Object.create(animal);
dog.bark = () => 'woof';
dog.bark(); // 'woof'
dog.eat(); // 'eating'(沿 [[Prototype]] 找到 animal)
dog.__proto__ === animal; // true(勿在生产改 __proto__)
Object.getPrototypeOf(dog) === animal; // 推荐 API
查找顺序:自身属性 → 原型 → 原型的原型 → … → null。
构造函数与 new
function Lesson(title) {
this.title = title;
}
Lesson.prototype.render = function () {
return `<h1>${this.title}</h1>`;
};
const l = new Lesson('JS 进阶');
l.render(); // '<h1>JS 进阶</h1>'
new 步骤:创建对象 → 绑定 this → 执行构造函数 → 关联原型 → 返回对象。
class 语法
class Track {
#slug; // 私有字段
constructor(slug, title) {
this.#slug = slug;
this.title = title;
}
get slug() {
return this.#slug;
}
static listUrl() {
return '/api/tracks';
}
}
class Lesson extends Track {
constructor(slug, title, order) {
super(slug, title);
this.order = order;
}
}
class 本质是原型继承的语法糖;方法定义在 Track.prototype 上。
Symbol
const ID = Symbol('id');
const user = {
name: 'Lee',
[ID]: 42,
};
Object.keys(user); // ['name'] — Symbol 不可枚举
user[ID]; // 42
const META = Symbol.for('app.meta');
Symbol.for('app.meta') === META; // true(全局注册表)
库作者用 Symbol 避免与用户属性名冲突;Symbol.iterator 定义可迭代协议。
属性描述符
const obj = {};
Object.defineProperty(obj, 'locked', {
value: 1,
writable: false,
enumerable: false,
configurable: false,
});