“为什么在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操作符测试对象在其原型链中是否具有构造函数的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
我花了一段时间才弄明白,但它确实值得花时间。首先,让我们看看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
,它是{}
。现在,它正在尝试查找函数的pr中是否存在相同的对象{}