1. 原型(Prototype)
每个JavaScript函数都有一个prototype属性,它指向该函数的原型对象。原型对象包含了所有实例共享的属性和方法,是实现继承机制的基础。
2. 原型链(Prototype Chain)
每个对象都有一个__proto__属性,指向其构造函数的原型对象。属性访问的查找机制如下:
- 首先在对象本身查找
- 如果没有找到,通过
__proto__在构造函数的原型上查找 - 如果仍未找到,继续通过原型对象的
__proto__逐级向上查找 - 最终到达
Object构造函数的原型,其__proto__为null,这是原型链的终点
3. 继承(Inheritance)
3.1 构造函数继承
使用call/apply方法借助构造函数实现继承,但这种方式无法继承原型对象上的属性和方法。
3.2 原型链继承
将需要共享的属性和方法放置在原型对象上,通过让子类的原型等于父类的实例来实现继承。
// 实现call方法示例
Function.prototype.myCall = function(context, ...args) {
context = context || window;
const fn = Symbol('fn');
context[fn] = this;
const result = context[fn](...args);
delete context[fn];
return result;
};
4. new操作符执行机制
new操作符的执行过程:
-
创建一个新的空对象
-
将新对象与构造函数通过原型链连接
-
改变this指向,使其指向新创建的对象
-
根据构造函数的返回值决定最终返回结果:
- 无return语句:返回新对象
- return引用类型:返回该引用类型
- return非引用类型:忽略,返回新对象
// 自定义new方法实现
function myNew(parent, ...args) {
const obj = Object.create(null);
obj.__proto__ = parent.prototype;
const res = parent.apply(obj, args);
return res instanceof Object ? res : obj;
}
5. 封装(Encapsulation)
封装的主要作用:
- 隐藏实现细节:使代码模块化,提高可维护性
- 实现代码复用:通过继承扩展功能