“为什么在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 本质上,它是检查对象(不是对象的实例,而是构造函数本身)是否作为函数的实例。构造函

为什么在JavaScript中,函数的
对象实例
和对象的
函数实例
都返回
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
    be
    GetValue(lref)
  • rref
    作为计算
    ShiftExpression
    的结果
  • rval
    be
    GetValue(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
    be
    GetValue(lref)
  • rref
    作为计算
    ShiftExpression
    的结果
  • rval
    be
    GetValue(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中是否存在相同的对象
    {}