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_
来访问。