简体   繁体   English

为什么从绑定函数返回的`this`不能严格等于传递的原始值?

[英]Why doesn't `this` returned from bound function strictly equal passed primitive value?

I noticed that this returned from bound function doesn't strictly equal primitive value passed when binding. 我注意到, this从绑定的函数返回绑定时并没有经过严格等于原始值。

According to MDN when the original function is called [[BoundThis]] gets passed. 根据MDN,当调用原始函数[[BoundThis]]会被传递。

What is this returned from bound function? 什么是this从绑定的函数返回? Is it [[BoundThis]] ? [[BoundThis]]吗?

const fn = function() { return this }
const strBound = fn.bind('111')
const numBound = fn.bind(111)
const boolBound = fn.bind(true)

console.log(strBound()) // [String: '111']
console.log(strBound() == '111') // true
console.log(strBound() === '111') // false

console.log(numBound()) // [Number: 111]
console.log(numBound() == 111) // true
console.log(numBound() === 111) // false

console.log(boolBound()) // [Boolean: true]
console.log(boolBound() == true) // true
console.log(boolBound() === true) // false

Your function is not in strict mode, which means it will always implicitly cast its received this value to an object (and uses the global object upon receiving null / undefined ). 您的函数未处于严格模式,这意味着它将始终隐式将其接收到的this值转换为对象(并在接收null / undefined时使用全局对象)。 Your code will work as expected with 您的代码将按预期工作

function fn() {
    "use strict";
    return this;
}

Notice that one could reproduce the issue without bind . 注意, 无需bind即可重现该问题

This behaviour, as always, has been defined by the ECMAScript specification. 与以往一样,此行为已由ECMAScript规范定义。 In this case it takes a while to actually follow the different specifications, but if you are interested in the details, here you go. 在这种情况下,要花一些时间才能真正遵循不同的规范,但是如果您对这些细节感兴趣,可以继续。

19.2.3.2 Function.prototype.bind ( thisArg , ...args) 19.2.3.2 Function.prototype.bind(thisArg,... args)

[...] [...]

  1. Let F be BoundFunctionCreate (Target, thisArg, args). 令F为BoundFunctionCreate (目标,thisArg,args)。

[...] [...]

  1. Return F. 返回F。

9.4.1.3 BoundFunctionCreate (targetFunction, boundThis, boundArgs) 9.4.1.3 BoundFunctionCreate(targetFunction,boundThis,boundArgs)

[...] [...]

  1. Set the [[Call]] internal method of obj as described in 9.4.1.1. 设置obj的[[Call]]内部方法,如9.4.1.1所述。

9.4.1.1 [[Call]] ( thisArgument, argumentsList) 9.4.1.1 [[Call]] (thisArgument,argumentsList)

[...] [...]

  1. Return Call (target, boundThis, args). 返回调用 (target,boundThis,args)。

7.3.12 Call(F, V, [argumentsList]) 7.3.12 通话(F,V,[argumentsList])

[...] [...]

  1. Return F. [[Call]] (V, argumentsList). 返回F。 [[Call]] (V,argumentsList)。

9.2.1 [[Call]] ( thisArgument, argumentsList) 9.2.1 [[Call]] (thisArgument,argumentsList)

[...] [...]

  1. Perform OrdinaryCallBindThis (F, calleeContext, thisArgument). 执行OrdinaryCallBindThis (F,calleeContext,thisArgument)。

9.2.1.2 OrdinaryCallBindThis ( F, calleeContext, thisArgument ) 9.2.1.2 OrdinaryCallBindThis(F,calleeContext,thisArgument)

[...] [...]

  1. If thisMode is strict, let thisValue be thisArgument. 如果thisMode是严格的,则让thisValue为thisArgument。
  2. Else 其他
    • if thisArgument is null or undefined, then 如果thisArgument为null或未定义,则
      Let thisValue be calleeRealm.[[globalThis]]. 令thisValue为calleeRealm。[[globalThis]]。
    • Else 其他
      Let thisValue be ToObject (thisArgument). 令thisValue为ToObject (thisArgument)。

7.1.13 ToObject ( argument ) 7.1.13 ToObject(参数)

[...] [...]

Number: Return a new Number object whose [[NumberData]] internal slot is set to the value of argument. Number:返回一个新的Number对象,该对象的[[NumberData]]内部插槽设置为参数值。 See 20.1 for a description of Number objects. 有关Number对象的描述,请参见20.1。

String: Return a new String object whose [[StringData]] internal slot is set to the value of argument. 字符串:返回一个新的字符串对象,其[[StringData]]内部插槽设置为参数值。 See 21.1 for a description of String objects. 有关String对象的描述,请参见21.1。

  • A primitive string is not strictly equal to a string object with the same value. 基本字符串并不严格等于具有相同值的字符串对象。
  • A primitive number is not strictly equal to a number object with the same value. 基本数字并不严格等于具有相同值的数字对象。

Binding a function to a string primitive implicitly converts the string primitive into a String object. 将函数绑定到字符串基元会隐式将字符串基元转换为String对象。

When type coercion is in play, a string primitive and String object will match. 当强制类型播放时,字符串基元和String对象将匹配。

Without type coercion, they won't. 没有类型强制,他们就不会。

Ditto other kinds of primitives. 同上其他种类的图元。

 const prim = "x"; const obj = new String("x"); console.log(prim instanceof String); console.log(obj instanceof String); console.log(prim == obj); console.log(prim === obj); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM