构造函数/原型对象/类与继承

2022-12-14  本文已影响0人  欢西西西

一、new关键字

function Person(name) {
    this.name = name;
}

Person.prototype = {
    constructor: Person,
    sayName() {
        alert(this.name);
    }
};
  1. 在使用new创建对象时:
  1. 假如构造函数显式返回了一个非基础类型的数据,例如一个数组或function,那么构造函数里加的属性和原型上的方法都和这个对象无关。

  2. 自己实现,期待调用方式为:const user = create(Person, 'wxm');

function create() {
    let[target,...args] = arguments;
    if (!target) {
        throw new Error('请传入构造函数');
    }
    const o = Object.create(target.prototype); // 1. 创建空对象并链接原型对象
    const v = target.apply(o, args); // 2. 执行构造函数
    // 3. 根据构造函数的执行返回值决定返回结果
    if (typeof v === 'object' && v !== null) {
        return v;
    }
    return o;
}

二、Object.create 和 new Object

  1. const a = Object.create(b) ,创建一个原型对象为b的新对象,此时: a.__proto__ === b

  2. 可以用 const a = Object.create(null)来创建一个没有原型的对象,此时a.__proto__ === undefined

  3. const a = new Object()const a = {} 创建的对象都默认继承自 Object。此时:a.__proto__ === Object.prototype

  4. Object.setPrototypeOf()可以设置对象的原型对象,Object.setPrototypeOf(a, null) ,此时:a.__proto__ === undefined

三、prototype 和 constructor

function Person(name) {
    this.name = name;
}

Person.prototype = {
    constructor: Person,
    sayName() {
        alert(this.name);
    }
};

prototype和constructor 把构造函数和它的prototype对象关联在一起。

一个实例的原型对象是【它的__proto__指向的对象,构造函数的prototype并不是它的原型对象,依然是这个构造函数的__proto__,不要搞混

  1. [].__proto__ === Array.prototype

  2. Array.prototype.constructor === Array

  3. 相当于 [].__proto__.constructor === Array

如果不constructor会怎样?

constructor可以用来检测一个对象是否由某个构造函数创建的。obj.__proto__.constructor指向创建obj的构造函数,不写constructor就无法从实例上识别出这个对象是由哪个构造函数创建的

原型链

Array.prototype.__proto__ === Object.prototype

一个题外话

数组相关方法挂在Array.prototype对象上,所以数组可以访问到这些方法。 使用const arrayMethods = Object.create(Array.prototype) 创建了一个原型对象为Array.prototype的空对象,这样就能使用Object.defineProperty去重写对象的value属性,也就是重写这些数组方法,Vue2在做响应式数据时拦截数组方法就用的这种方法

image.png

四、继承

  1. 通过【绑定this为当前对象并执行一遍原构造函数】来继承属性
  2. 通过【将该构造函数的prototype指向原构造函数的原型对象】来继承方法
// 如果要继承自Person
function Girl() {
    Person.apply(this, arguments);
}

const _proto = Object.create(Person.prototype);
_proto.constructor = Girl;
Girl.prototype = _proto;

可以通过Girl.prototype.__proto__.constructor来得到Person这个构造函数,因为Girl.prototype.__proto__ === Person.prototype

五、ES6 类与继承

image
上一篇下一篇

猜你喜欢

热点阅读