当前位置: 首页 > 后端技术 > Node.js

ECMA规范Node.js中Object和Function的关系

时间:2023-04-04 01:24:57 Node.js

为什么在JavaScript中“ObjectinstanceofFunction”和“FunctioninstanceofObject”都返回true?一、ECMA5.1规范中instanceof/*instanceof是如何由ECMA5.1规范定义的:产生式RelationalExpression:RelationalExpressioninstanceofShiftExpression的求值如下:让lref是计算RelationalExpression的结果。设lval为GetValue(lref)。令rref为评估ShiftExpression的结果。设rval为GetValue(rref)。如果Type(rval)不是Object,则抛出TypeError异常。如果rval没有[[HasInstance]]内部方法,则抛出TypeError异常。返回以参数lval调用rval的[[HasInstance]]内部方法的结果。------>不是所有的对象都会有[[HasInstance]]内部方法,但是函数。console.log(对象实例{});TypeError:Expectingafunctionininstanceofcheck,butgot*/二、ECMA5.1规范中[[HasInstance]]/*how[[HasInstance]]已在ECMA5.1规范中定义:假设F是一个Function对象。当使用值V调用F的[[HasInstance]]内部方法时,执行以下步骤:如果V不是对象,则返回false。设O是调用F的[[Get]]内部方法并使用属性名称“prototype”的结果。如果Type(O)不是Object,则抛出TypeError异常。重复让V成为V的[[Prototype]]内部属性的值。如果V为null,则返回false。如果O和V引用同一个对象,则返回true。------->取F的原型属性与O的[[Prototype]]内部属性进行比较,直到为null或者F的原型与O相同。*/三、ECMA5.1规范中[[prototype]]/*什么是[[prototype]]内部属性:所有对象都有一个名为[[Prototype]]的内部属性。此属性的值为null或一个对象,并且是用于实现继承。本机对象是否可以将宿主对象作为其[[Prototype]]取决于实现。每条[[Prototype]]链都必须有有限的长度(即从任何对象开始,递归访问[[Prototype]]内部属性最终一定会导致空值)。-------->我们可以得到这个带有Object.getPrototypeOf函数的内部属性*//*[[HasInstance]]还谈到了另一个称为原型的属性,它是特定于Function对象的。prototype属性的值用于在Function对象作为新创建对象的构造函数调用之前初始化新创建对象的[[Prototype]]内部属性。------>当一个函数对象用作构造函数,将创建一个新对象,并且新对象将使用此原型属性初始化其内部[[Prototype]]------>functionTest(){}Test.prototype.print=console.log;console.log(Object.getPrototypeOf(newTest())===Test.prototype);#true*/console.log("------------------------------------------------------"+"\n\n");四、分析过程//分析:console.log(ObjectinstanceofFunction);//true//会获取Function.prototype首先,它会尝试//并查找该对象是否在Object的原型层次结构中。让我们看看结果如何)===Function.prototype);//true//因为Function.prototype匹配对象的内部属性[[Prototype]],它返回trueconsole.log(FunctioninstanceofObject);//trueconsole.log(Object.prototype);//{}console.log(Object.getPrototypeOf(Function));//[函数:空]console.log(Object.getPrototypeOf(Function)===Object.prototype);//falseconsole.log(Object.getPrototypeOf(Object.getPrototypeOf(Function)));//{}Object.getPrototypeOf(Object.getPrototypeOf(Function))===Object.prototype//true//这里,首先我们得到Object.prototype,它是{}.//现在它试图查找Function的原型链中是否存在相同的对象{}。//Function的直接父级是Emptyfunction.console.log(Object.getPrototypeOf(Function));//[Function:Empty]//和Object.prototypeconsole.log(Object.getPrototypeOf(Function)===Object.prototype);//false//但是[[HasInstance]]算法不止于此.重复并上一层console.log(Object.getPrototypeOf(Object.getPrototypeOf(Function)));//{}//这和Object.prototype是一样的。这就是为什么它返回true.console.log("------------------------------------------------------"+"\n\n");五、证明流程console.log(ObjectinstanceofFunction);//trueconsole.log(FunctioninstanceofObject);//trueconsole.log(Object.prototype);//{}console.log(Object.getPrototypeOf(Function));//[函数:空]console.log(Object.getPrototypeOf(Function)===Object.prototype);//falseconsole.log(Object.getPrototypeOf(Object.getPrototypeOf(Function)));//{}console.log(Object.getPrototypeOf(Object.getPrototypeOf(Function))===Object.prototype);//trueconsole.log(Object.getPrototypeOf(Function));//[Function:Empty]console.log(Object.getPrototypeOf(Function)===Object.prototype);//falseconsole.log(Object.getPrototypeOf(Object.getPrototypeOf(Function)));//{}console.log("--------------------------------------------------"+"\n\n");