Javascript原型、构造函数、实例的关系

1. 原型、构造函数、实例的关系

  1. 原型:

    • 原型通过constructor指向构造函数,原型如果是自定义对象且没有明确将constructor指向构造函数,则原型的constructor指向函数的基类Function。
    • 原型通过方法isPrototypeOf检查是否和实例之间有关系;
  2. 构造函数:

    • 构造函数的prototype指向原型
    • 因为构造函数和原型可以生成多个实例,所以它两者不关心其所对应的实例,没有直接获取其对应实例的途径。
    • 构造函数通过instanceof 查看和实例之间是否有关系。
  3. 实例

    • 实例的__proto__检查指向其原型;
    • 实例的constructor检查是否和构造函数有关系
    • 实例通过Object.getPrototypeOf(实例)可以查看其原型是谁
    • 实例和原型的constructor都明确的指向构造函数,但原型如果是自定义对象且没有明确将constructor指向构造函数,则原型的constructor指向函数的基类Function。

2. 实例化的过程

  1. 创建一个对象

  2. 创建__proto__属性指向构造函数的prototype属性,创建constructor属性指向自己的构造函数;

  3. 将构造函数的所有私有属性方法复制到自己身上;
    以下为函数实现:

     function Move(name) {
         this.name = name
         this.say = function() {
             console.log('hello,say')
         }
     }
     Move.prototype.age = 23;
     let s  = new Move('tt');
     console.log(s);
    // new关键字的函数实现
     function newFunc(fn,...rest) {
         let obj = {};                            
         obj.constructor = fn;                 
         obj.__proto__ = fn.prototype;
         fn.call(obj,rest);                       
         return obj;
     }
    
     let newS = newFunc(Move, 'tt')
     console.log(newS) 
    

3. 扩展

对象两两不相等,因为他们指针所对应的实际存储位置不一致,如果一致,也是相等的。

    function Move() {}
    let obj = {age: 23}
    Move.prototype = obj;
    var m = new Move()

    console.log(Move.prototype === m.__proto__)    // true
    console.log(Move.prototype === obj)            // true
    console.log(m.__proto__ === obj)               // true
    console.log(obj.isPrototypeOf(m))              // true
    console.log(Object.getPrototypeOf(m))          // { age: 23 }
   console.log(m instanceof Move)                   // true
posted @ 2019-05-02 11:32  六石  阅读(699)  评论(0编辑  收藏  举报