gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 03:12:27 28 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.

就是这么简单。获取 Fprototype 属性并将其与 O[[Prototype]] 内部属性进行比较,直到它变为 nullFprototypeO 相同。

[[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]] 属性。例如,

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 的直接父级是 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/23622695/

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