原型

107 阅读1分钟

原型概念

说到原型,要理解构造函数原型对象

    function fn (){} // 构造函数就是声明函数
    // 声明函数后,浏览器会自动在内存中创建一个对象{},这个对象叫原型对象

上图分析如下:

  • 实例对象stu被创建后跟函数Student没啥关系

  • 实例对象若有多个:stu1,stu2,stu3都会有__proto__属性指向同一个原型对象

  • 显示原型:函数中prototype属性就叫做显示原型

  • 隐式原型:实例对象中__proto__属性就叫做隐式原型

  • 对象的隐式原型和函数的显示原型相等

    const stu = new Student()  
    stu.__proto__   // {constructor:f} 隐式
    Student.prototype // {constructor:f} 显示
    Student.prototype.constructor // Student(){} 
    
    const stu1 = new Student()
    const stu2 = new Student()
    stu1.__proto__ === stu2.__proto__ // true
    stu.__proto__ === Student.prototype // true
    
    Student.__proto__ // () {}
    stu.prototype // undefined
    // 可以看出,只有函数才有显示原型
    // 函数和对象都可以有隐式原型
    Student.__proto__ === Function.prototype // true
    // Student 其实是Function的实例,所以上式成立
    Function.prototype === Function.__proto__ // true
    // 这说明Function很特殊,自己的显示原型=自己隐式原型
typeOf Number  // function
typeOf String // function
typeOf Object // function
typeOf Array // function
typeOf {} // obejct
Number instanceof Object // true
String instanceof Object // true
Object instanceof Object // true
Array instanceof Object // true

Number instanceof Function // ture
String instanceof Function // true
Object instanceof Function // true
Array instanceof Function // true

// 可以看出,Function和Object互相继承

原型链

任何对象直接调用方法,例如obj.foo(),在实例本身没有这个属性的情况下,都是从其__proto__属性上查找的,也就是从该对象的构造函数的prototype属性上查找。。

这里有一道典型的题目就是考对上面几条的理解,我们都知道Object.prototype.toString方法可以用来判断数据类型,那么用Object.toString可以吗。 答案是:不可以。 因为Object.toString是Object.proto.toString,也就是Function.prototype.toString,和Object.prototype.toString根本不是同一个函数。