面向对象

9 阅读2分钟

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操作符的执行过程:

  1. 创建一个新的空对象

  2. 将新对象与构造函数通过原型链连接

  3. 改变this指向,使其指向新创建的对象

  4. 根据构造函数的返回值决定最终返回结果:

    • 无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)

封装的主要作用:

  • 隐藏实现细节:使代码模块化,提高可维护性
  • 实现代码复用:通过继承扩展功能