new和instanceof的内部机制
new
代码例子
var Func=function(){
};
var func=new Func ();
new共经过4个阶段
1.创建一个空对象
var obj = new Object();
2.设置原型链
obj.__proto__=Func.prototype;
3.让Func中的this指向obj,并执行Func的函数体。
var result = Func.call(obj);
4.判断Func的返回值类型,如果是基本值类型,返回obj;如果是引用类型,就返回这个引用类型的对象。
if (typeof(result) == "object"){
func=result;
}
else{
func=obj;;
}
instanceof
instanceof运算符用于判断一个对象的原型链是否存在一个构造函数的prototype属性。
语法:object instanceof constructor
参数:object(要检测的对象) constructor(某个构造函数)
描述:instanceof运算符用来检测constructor.prototype是否存在于参数object的原型链上
下面通过代码阐述instanceof的内部机制,假设有x instanceof y 一条语句,,则其内部实际做了如下判断:
while(x.__proto__!==null) {
if(x.__proto__===y.prototype) {
return true;
break;
}
x.__proto__ = x.__proto__.proto__;
}
if(x.__proto__==null) {return false;}
x会一直沿着隐式原型链__proto__向上查找直到x.__proto__.__proto__.......===y.prototype为止,如果找到则返回true,即x为y的实例,否则返回false,x不是y的实例。
相关面试题
function F() {}
function O() {} O.prototype = new F();
var obj = new O(); console.log(obj instanceof O); // true
console.log(obj instanceof F); // true
console.log(obj.__proto__ === O.prototype); // true
console.log(obj.__proto__.__proto__ === F.prototype); // true
根据new的内部机制改写代码
function F() {}
function O() {} var obj = (function () {
var obj1 = {};
obj1.__proto__ = F.prototype; // new F();
O.prototype = obj1; // O.prototype = new F();
obj.__proto__ = O.prototype; // new O();
obj.__proto__ = obj1;
return obj;
})()
如果改一下代码顺序,结果将不同
function F() {}
function O() {} var obj = new O();
O.prototype = new F(); console.log(obj instanceof O); // false
console.log(obj instanceof F); // false
console.log(obj.__proto__ === O.prototype); // false
console.log(obj.__proto__.__proto__ === F.prototype); // false
顺便扩展一下原型和原型链
构造函数:function Foo() {};
实例对象:let f1=new Foo;
let o1=new Foo();
概念:
1、构造函数:用来初始化新创建的对象的函数是构造函数。在例子中,Foo()函数是构造函数。
2、实例对象:通过构造函数的new操作创建的对象是实例对象。可以用一个构造函数,构造多个实例对象
每个函数都有 prototype
属性,除了 Function.prototype.bind()
,该属性指向原型。
每个对象都有 __proto__
属性,指向了创建该对象的构造函数的原型。其实这个属性指向了 [[prototype]]
,但是 [[prototype]]
是内部属性,我们并不能访问到,所以使用 _proto_
来访问。