Javascript 如何知道何时在JS中的函数上使用.bind()?
(我知道这个问题,但答案并没有告诉我需要知道什么。) 我遇到过这样的情况:我需要在JavaScript中的函数上使用,以便将Javascript 如何知道何时在JS中的函数上使用.bind()?,javascript,function,scope,this,bind,Javascript,Function,Scope,This,Bind,(我知道这个问题,但答案并没有告诉我需要知道什么。) 我遇到过这样的情况:我需要在JavaScript中的函数上使用,以便将this或局部/类变量传递给函数。然而,我仍然不知道什么时候需要它 确切地说,知道函数中何时会或何时不会有此或局部/类变量的标准是什么?你如何解释这一点? 例如: 当创建、包装或传递新的匿名函数(){}时 当使用类成员函数、类getter/setter函数或老式的原型函数成员函数(作为类的函数)时 在全球范围内 在for或forEach循环中,或在其任何变体中 在闭包中是
this
或局部/类变量传递给函数。然而,我仍然不知道什么时候需要它
确切地说,知道函数中何时会或何时不会有此
或局部/类变量的标准是什么?你如何解释这一点?
例如:
- 当创建、包装或传递新的匿名
时函数(){}
- 当使用
成员函数、类
getter/setter函数或老式的类
成员函数(作为类的函数)时原型函数
- 在全球范围内
- 在
或for
循环中,或在其任何变体中forEach
- 在闭包中是外部功能还是内部功能
- 在各种JS操作中,例如
或Array.prototype.forEach.call()
[].forEach.call()
- 在各种JS库和脚本中,哪些可能有自己的自定义实现
我提出这一要求的主要原因是要意识到潜在的陷阱,避免依赖于反复试验。在以下情况下,您需要使用
bind
(或类似方法):
- 该函数是传统的(
关键字)函数或方法(在function
或对象文本中),并且类
- 调用该函数的方式不是显式设置
,就是将其设置为不正确的值this
this
的值是由调用方设置的,不是函数本身的一部分。(详情及详情)
例如,考虑:
const obj = {
method() {
console.log(this === obj);
}
};
现在,当我们执行obj.method()
时,我们使用语法(调用属性访问器操作的结果)来指定此将是什么,因此:
obj.method();
// => true
但假设我们这样做:
const m = obj.method;
现在,只需调用m()
即可将this
设置为默认的this
(在严格模式下未定义,全局对象在松散模式下):
我们可以为调用显式设置此
的另一种方法是通过调用
(及其表亲应用
):
一些调用回调的函数允许您指定此
要使用的内容forEach
会执行以下操作,作为回调后的参数:
[1].forEach(m, obj);
// ^ ^^^---- the value to use as `this` in callback
// \-------- the callback to call
// => true
下面是一个活生生的例子:
const obj={
方法(){
console.log(this==obj);
}
};
obj.method();
//=>true,`this`设置为`obj`是因为您在
//属性访问器的结果
常数m=对象方法;
m();
//=>false,`this`是默认的`this`而`this`不是
//通过语法或'call'显式指定`
m、 呼叫(obj);
//=>true,`this`是通过`call显式设置的`
[1] .forEach(m,obj);
//=>true,`this`是通过`forEach``thisArg`参数显式设置的
Mozilla开发者网络提供了一些关于指定不同情况的优秀文档:
查看链接,了解此
如何在不同的上下文中工作,因此何时应使用绑定
强制绑定函数的不同此
上下文
通常,bind
用于转移函数的“所有权”。具体地说,根据我的经验,它早在创建类之前就被用来强制将对象方法绑定到所讨论的对象。当使用箭头函数时,它也很有用,因为箭头函数有不同的上下文。将它们的答案归功于和,它们提供了有用的信息。以下4个答案/文章也很有帮助:
然而,这些不是完全完整的,就是冗长的。因此,我决定将我的所有发现与代码示例结合在一起,形成一个答案
在确定函数中是否存在此
或局部/类变量时,需要考虑几个因素:
- 函数的包含范围
- 调用链中的直接前导
- 函数是直接调用还是间接调用
注意:还有严格模式(产生未定义的
,而不是窗口
对象)和箭头函数(不会从包含的范围更改此
)
以下是明确的规则:
- 默认情况下,
此
是全局对象,在浏览器世界中是窗口
- 在全局范围内的函数中,
此
仍将是窗口
,它不会更改
- 在
类
或函数类(新函数(){}
)中的成员函数内,在函数类的原型(funcClass.prototype.func=function(){}
)内,在具有此
的相邻成员函数调用的函数内,或在对象中映射的函数内({key:function>)(){}
)或存储在数组中([function(){}]
),如果函数是以类/对象/数组作为调用链中的直接前导直接调用的(class.func()
,this.func()
,obj.func()
,或arr[0]()
),此
引用类/对象/数组实例
- 在任何闭包的内部函数(函数中的任何函数)、返回函数内部、调用链中以普通变量引用作为其直接前导调用的函数内部(,无论它实际位于何处!),或间接调用的函数内部(即传递
m.call(obj);
// => true
[1].forEach(m, obj);
// ^ ^^^---- the value to use as `this` in callback
// \-------- the callback to call
// => true