“为什么在JavaScript中同时使用这两种语言?”;“函数的对象实例”;及;“对象的函数实例”;返回真值?
为什么在JavaScript中,函数的“为什么在JavaScript中同时使用这两种语言?”;“函数的对象实例”;及;“对象的函数实例”;返回真值?,javascript,function,object,Javascript,Function,Object,为什么在JavaScript中,函数的对象实例和对象的函数实例都返回true 我在Safari WebInspector中试用过它。来自: instanceof操作符测试对象在其原型链中是否具有构造函数的prototype属性 function Dog () {} var myCrazyDog = new Dog(); myCrazyDog.__proto__ === Dog.prototype // true 本质上,它是检查对象(不是对象的实例,而是构造函数本身)是否作为函数的实例。构造函
对象实例
和对象的函数实例
都返回true
我在Safari WebInspector中试用过它。来自:
instanceof操作符测试对象在其原型链中是否具有构造函数的prototype属性
function Dog () {}
var myCrazyDog = new Dog();
myCrazyDog.__proto__ === Dog.prototype // true
本质上,它是检查对象
(不是对象
的实例,而是构造函数本身)是否作为函数的实例。构造函数
位于其原型链的某个位置
事实上:
> Function.__proto__.__proto__ === Object.prototype
true
> Object.__proto__ === Function.prototype
true
这就解释了为什么函数的
对象实例以及相反的情况。我花了一段时间才弄明白,但花的时间确实值得。首先,让我们看看instanceof
是如何工作的
引用
instanceof
操作符测试对象的原型链中是否包含构造函数的prototype
属性
function Dog () {}
var myCrazyDog = new Dog();
myCrazyDog.__proto__ === Dog.prototype // true
[instanceof]
现在,让我们看看ECMA 5.1规范是如何定义的
生产RelationalExpression:shiftextexpression的RelationalExpression实例计算如下:
让lref
作为计算RelationalExpression
的结果
让lval
beGetValue(lref)
让rref
作为计算ShiftExpression
的结果
让rval
beGetValue(rref)
如果Type(rval)
不是对象,则抛出TypeError
异常
如果rval
没有[[HasInstance]]
内部方法,则抛出TypeError
异常
返回调用带有参数lval
的[[HasInstance]]]
内部方法的结果
首先计算左侧和右侧表达式(GetValue
),然后右侧结果应该是具有[[HasInstance]]]
内部方法的对象。并非所有对象都有[[HasInstance]]
内部方法,而是函数。例如,以下操作将失败
console.log(Object instanceof {});
# TypeError: Expecting a function in instanceof check, but got #<Object>
实际问题
现在让我们回到实际问题上来。让我们看第一个案例
console.log(Object instanceof Function);
# true
它将首先获取函数.prototype
,然后尝试查找该对象是否在对象的prototype层次结构中。让我们看看结果如何
console.log(Function.prototype);
# [Function: Empty]
console.log(Object.getPrototypeOf(Object));
# [Function: Empty]
console.log(Object.getPrototypeOf(Object) === Function.prototype);
# true
由于函数.prototype
匹配对象的内部属性[[prototype]]
,因此它返回true
现在我们来看第二个例子
console.log(Function instanceof Object);
# true
console.log(Object.prototype);
# {}
console.log(Object.getPrototypeOf(Function));
# [Function: Empty]
console.log(Object.getPrototypeOf(Function) === Object.prototype);
# false
console.log(Object.getPrototypeOf(Object.getPrototypeOf(Function)));
# {}
Object.getPrototypeOf(Object.getPrototypeOf(Function)) === Object.prototype
# true
这里,首先我们得到对象.prototype
,它是{}
。现在,它正在尝试查找相同的对象{}
是否存在于函数的原型链中。函数的直接父函数是和空函数
console.log(Object.getPrototypeOf(Function));
# [Function: Empty]
它与对象不同。原型
console.log(Object.getPrototypeOf(Function) === Object.prototype);
# false
但是[[HasInstance]]
算法并没有就此停止。它重复并上升一级
console.log(Object.getPrototypeOf(Object.getPrototypeOf(Function)));
# {}
这与Object.prototype
相同。这就是为什么返回true
问题中的混淆源于JavaScript(ECMAScript)中函数*固有的双重性质
js中的函数既是常规函数又是对象。把它们想象成算法杰基尔博士和海德先生。它们看起来像是外部的对象,但在内部,它们只是你的好的老js函数和它们的所有怪癖,或者可能是相反的方式
JavaScript确实是一项棘手的业务:)
回到你的问题,借用MDN上出现的语法:
构造函数的对象实例
将其应用于代码中的第一条语句:
函数的对象实例
这里有Object
,一个用作对象初始值设定项的构造函数,但由于函数在js中具有双重生命,因此它附带了特定于对象的道具和方法,使其有效地成为一个对象
因此,声明中的第一个条件已经满足。我们还需要研究其他条件或操作数
Function
正如您可能已经注意到的,它也是函数构造函数,但是在执行这个特定语句的过程中,我们对它的另一个对象端不感兴趣
因此,句法条件都满足,即“宾语”和“构造器”。现在我们可以继续调查他们的遗传关系,以及他们之间是否有联系
由于Object
本身就是一个工作函数,因此假设它的内部原型prop指向函数是很有意义的。prototype
对象引用,因为在js中,所有的函数都通过相同的位置函数继承它们的prop和方法。prototype
true
无疑是运算符执行的该比较的唯一预期结果
对于另一种情况:
对象的函数实例
因为我们已经确定js中的函数也有对象端。他们从object.prototype
中得到了他们奇特的特定于对象的玩具,这是有道理的,因此他们构成了对象构造函数的实例
希望我的解释和寓言不会增加混乱。:)
*:不仅是在js中具有双重生活的功能。js中几乎所有的数据类型都有对象的阴暗面,有助于轻松完成操作和操作。最糟糕的特性实际上是函数本身就是一个实例<代码>Functi的函数实例
console.log(Object instanceof Function) // true
console.log(Object.__proto__ === Function.prototype) // true
Object ---> Function.prototype ---> Object.prototype ---> null
Function ---> Function.prototype ---> Object.prototype ---> null
console.log(Object instanceof Object) // true
console.log(Object.__proto__ === Function.prototype) // true
console.log(Object.__proto__.__proto__ === Object.prototype) // true
console.log(Function instanceof Object) // true
console.log(Function.__proto__ === Function.prototype) // true
console.log(Function.__proto__.__proto__ === Object.prototype) // true
Function ---> Function.prototype ---> Object.prototype ---> null
console.log(Function instanceof Function) // true
console.log(Function.__proto__ === Function.prototype) // true
console.log(Function.__proto__.__proto__ === Object.prototype) // true
console.log(Object instance of Function) // true
console.log(Function instance of Function) // true
console.log(Function.prototype instanceof Object); // true