美文网首页
构造函数/原型对象/类与继承

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

作者: 欢西西西 | 来源:发表于2022-12-14 17:52 被阅读0次

    一、new关键字

    function Person(name) {
        this.name = name;
    }
    
    Person.prototype = {
        constructor: Person,
        sayName() {
            alert(this.name);
        }
    };
    
    1. 在使用new创建对象时:
    • 创建一个新对象,并且这个对象的原型指向构造函数的prototype属性
    • 构造函数的this指向这个新对象,执行构造函数
    • 返回这个新对象或者构造函数里显式返回的对象
    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就无法从实例上识别出这个对象是由哪个构造函数创建的

    • [].__proto__.constructor === Array
    • [].constructor === Array

    原型链

    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

    相关文章

      网友评论

          本文标题:构造函数/原型对象/类与继承

          本文链接:https://www.haomeiwen.com/subject/flllqdtx.html