美文网首页
深入理解Javascript中的Prototype原型

深入理解Javascript中的Prototype原型

作者: HalShaw | 来源:发表于2019-07-17 22:25 被阅读0次
Prototype
  • 刚开始学Javascript的时候觉得很简单,其中的东西也就是那是基本的,但是还是太年轻,最近因为面试中常被问到关于原型和原型链的问题,然后自己也是模棱两可的,含含糊糊说不清楚,所以痛下思定,决定好好下一番功夫来搞懂吃透原型与原型链究竟是什么。

关于new

new的过程

  • 新生成了一个对象
  • 链接到原型
  • 绑定 this
  • 返回新对象
    知道了new的原理后,也可以自己实现一个new函数:
function myNew() {
    // 创建一个空的对象
    let obj = new Object()
    // 获得构造函数
    let Con = [].shift.call(arguments)
    // 链接到原型
    obj.__proto__ = Con.prototype
    // 绑定 this,执行构造函数
    let result = Con.apply(obj, arguments)
    // 确保 new 出来的是个对象
    return typeof result === 'object' ? result : obj
}

先来看几个例子:

  • 普通函数
function test(name){
    console.log(name);  
}
typeof(test) // function
  • 使用new新建对象
function test(name){
    console.log(name);  
}

var te = new test("Hal");
typeof(te) // object
console.log(JSON.stringify(test.prototype)) //{},是个空对象
console.log(JSON.stringify(te.prototype)) //undefined
  • 直接声明的函数拥有prototype这个属性,而new构造出来的函数不存在prototype

关于prototype

每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象 prototype,这个对象就是我们所说的prototype,每一个对象都会从prototype"继承"属性。除了new出来的函数,每个函数都有一个prototype属性,如下,在prototype上可以设置属性,然后打印出一些东西:

function Employee() {}

// prototype是函数才会有的属性
Employee.prototype.name = 'Hal';
var employee1 = new Employee();
var employee2 = new Employee();
console.log(employee1.name) // Hal
console.log(employee2.name) // Hal
console.log(employee1.constructor) // Employee() {}
console.log(employee1.constructor.name) // Employee
console.log(employee1.prototype) // undefined
console.log(employee1.__proto__) // {name: "Hal", constructor: ƒ}
console.log(Employee.prototype) // {name: "Hal", constructor: ƒ}
console.log(Employee.prototype === employee1.__proto__) // true
console.log(Employee.prototype.constructor === Employee) // true

关于__proto__

从刚才的例子中已经可以很清楚地看出了,employee1的__proto__和Employee.prototype是相等的,也就是指向同一个对象,也就是说,实例中有一个__proto__指针指向构造函数的prototype。使用Object.getPrototypeOf__proto__是同样的效果。

Object.getPrototypeOf(employee1) === Employee.prototype //true

关于constructor

从上面可以看到,原型prototype里面还有一个constructor的属性,然后这个constructor又指向了函数本身。
好像有一点绕,但是看一下下面的图就一目了然了:

原型链

总结

  • Object 是所有对象的祖先,所有对象都可以通过 __proto__ 找到它
  • Function 是所有函数的祖先,所有函数都可以通过 __proto__找到它
  • Function.prototypeObject.prototype 是两个特殊的对象,由引擎创建,而且Function.__proto__.__proto__是指向Object.prototype
    即:
    Function.__proto__.__proto__ === Object.prototype // true
  • 除了以上两个特殊对象,其他对象都是通过构造器 new 出来的
    函数的 prototype 是一个对象,也就是原型
  • 对象的 __proto__ 指向原型, __proto__ 将对象和原型连接起来组成了原型链

参考

相关文章

网友评论

      本文标题:深入理解Javascript中的Prototype原型

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