关于new
和instanceof
的内部机制
1.创建一个新对象,同时继承对象类的原型。,即
Person.prototype
2.执行对象类的构造函数,同时该实例的属性和方法被
this
所引用,即this
指向新构造的实例3.如果构造函数
return
了一个新的’对象’,那么这个对象就会取代整个new出来的结果。如果构造函数没有return
对象,那么就会返回步骤1所创建的对象,即隐式返回this。(一般情况下构造函数不会返回任何值)
Code:
1 | function Person(name) { |
- Object是所有对象的爸爸,所有的对象都可以通过
__proto__
找到它 - Function是所有函数的爸爸,所有函数都可以通过
__proto__
找到它 Function.prototype
和Object.prototype
是两个特殊的对象,他们由引擎来创建- 除了以上的两个对象,其他所有的对象都是通过构造器
new
出来的 - 函数的
prototype
是一个对象,也就是原型 - 对象的
__proto__
指向原型,__proto__
将对象和原型连接起来组成了原型链
下面代码阐述instanceof
的内部机制,假设现在有x instanceof y
的一条语句,其内部实际上做了如下判断:
来自MDN的instanceof
的解释
instanceof运算符用于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置
1 | function instance_of(L, R) { |
1 | function Rocker(name){ |
(1)处,我们创建了一个空对象(准确的说是克隆了Object.prototype
对象)
(2)处取到构造函数,赋值给Constructor
变量(通过[].shift.call(arguments)
将arguments
对象转换为数组),也就是说Rocker构造函数变为Constructor
的一个引用了
(3)将Constructor.prototype
(也就是Rocker.prototype
)赋值给刚刚创建的obj的原型链,或者说obj的原型链指向Constructor的原型
(4)我们用apply
来改变this
的指向,用obj代替Constructor构造函数内部的this,并把arguments作为参数传入(在第2步时已经用shift把第一个参数去除了),此时的ret已经是一个合格的实例了!)
(5)返回时判断ret是否是对象,如果不是就返回一个空对象
prototype
是用于类的(Person),而Object.getPropertyOf()
是作用于实例的(instances),两者的功能一致。
1 | function Foo () {} |
因此当执行var o = new Foo()
时
JavaScript实际执行的是:
1 | var o = new Object() |