gpt4 book ai didi

javascript - 为什么在 JavaScript 中 "Object instanceof Function"和 "Function instanceof Object"都返回 true?

转载 作者:行者123 更新时间:2023-11-28 04:57:02 29 4
gpt4 key购买 nike

为什么在 JavaScript 中,Object instanceof FunctionFunction instanceof Object 都返回 true

我在 Safari WebInspector 中尝试过。

最佳答案

我花了一段时间才弄清楚,但确实值得花时间。首先,让我们看看如何instanceof有效。

引用自MDN ,

The instanceof operator tests whether an object has in its prototype chain the prototype property of a constructor.

[instanceof]

现在,让我们看看如何 instanceof 由 ECMA 5.1 规范定义,

The production RelationalExpression: RelationalExpression instanceof ShiftExpression is evaluated as follows:

  1. Let lref be the result of evaluating RelationalExpression.
  2. Let lval be GetValue(lref).
  3. Let rref be the result of evaluating ShiftExpression.
  4. Let rval be GetValue(rref).
  5. If Type(rval) is not Object, throw a TypeError exception.
  6. If rval does not have a [[HasInstance]] internal method, throw a TypeError exception.
  7. Return the result of calling the [[HasInstance]] internal method of rval with argument lval.

首先计算左侧和右侧表达式 ( GetValue ),然后右侧结果应该是带有 [[HasInstance]] 的对象内部方法。并非所有对象都会有 [[HasInstance]]内部方法,但是函数。例如,以下将失败

console.log(Object instanceof {});
# TypeError: Expecting a function in instanceof check, but got #<Object>

[[HasInstance]]

现在,让我们看看如何 [[HasInstance]] 已在 ECMA 5.1 规范中定义,

Assume F is a Function object.

When the [[HasInstance]] internal method of F is called with value V, the following steps are taken:

  1. If V is not an object, return false.
  2. Let O be the result of calling the [[Get]] internal method of F with property name "prototype".
  3. If Type(O) is not Object, throw a TypeError exception.
  4. Repeat
    1. Let V be the value of the [[Prototype]] internal property of V.
    2. If V is null, return false.
    3. If O and V refer to the same object, return true.

就这么简单。采取prototype F的属性(property)并将其与 [[Prototype]] 进行比较O 的内部属性直到变成nullprototypeFO 相同.

[[prototype]]内部属性

首先让我们看看什么是 [[prototype]] internal property ,

All objects have an internal property called [[Prototype]]. The value of this property is either null or an object and is used for implementing inheritance. Whether or not a native object can have a host object as its [[Prototype]] depends on the implementation. Every [[Prototype]] chain must have finite length (that is, starting from any object, recursively accessing the [[Prototype]] internal property must eventually lead to a null value).

注意:我们可以通过 Object.getPrototypeOf 获取这个内部属性。功能。

prototype属性

[[HasInstance]]还谈到另一个名为 prototype 的属性,特定于 Function对象。

The value of the prototype property is used to initialise the [[Prototype]] internal property of a newly created object before the Function object is invoked as a constructor for that newly created object.

这意味着,当函数对象用作构造函数时,将创建一个新对象,并且新对象将具有其内部 [[Prototype]]用这个 prototype 初始化属性(property)。例如,

function Test() {}
Test.prototype.print = console.log;
console.log(Object.getPrototypeOf(new Test()) === Test.prototype);
# true

实际问题

现在让我们回到实际问题。我们来看第一个案例

console.log(Object instanceof Function);
# true

它将获取Function.prototype首先,它会尝试查找该对象是否在 Object 的原型(prototype)层次结构中。让我们看看结果如何

console.log(Function.prototype);
# [Function: Empty]
console.log(Object.getPrototypeOf(Object));
# [Function: Empty]
console.log(Object.getPrototypeOf(Object) === Function.prototype);
# true

Function.prototype匹配Object的内部属性 [[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

在这里,首先我们得到Object.prototype ,即{} 。现在它正在尝试查找是否有相同的对象 {} Function中有吗?的原型(prototype)链。 Function 的直接父级is 和 Empty 函数。

console.log(Object.getPrototypeOf(Function));
# [Function: Empty]

它与 Object.prototype 不同。

console.log(Object.getPrototypeOf(Function) === Object.prototype);
# false

但是[[HasInstance]]算法并不止于此。它重复并上升一级

console.log(Object.getPrototypeOf(Object.getPrototypeOf(Function)));
# {}

这与 Object.prototype 相同。这就是为什么返回 true .

关于javascript - 为什么在 JavaScript 中 "Object instanceof Function"和 "Function instanceof Object"都返回 true?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42465023/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com