Javascript 正在丢失'this'关键字的显式绑定

Javascript 正在丢失'this'关键字的显式绑定,javascript,this,Javascript,This,this关键字如何丢失显式绑定并使用默认绑定覆盖的示例/场景是什么?下面是一个示例代码段,它使用call方法将this关键字显式绑定到一个对象。对该代码的哪些理论添加会改变该代码的值?当硬绑定this关键字时,我们要保护代码不受哪些具体问题的影响 function foo(){ console.log(this.bar); // outputs: 9 } var obj = { bar: 9 }; foo.call(obj); 一般来说,这个没有“显式”绑定。此的值根据调用的性质在

this
关键字如何丢失显式绑定并使用默认绑定覆盖的示例/场景是什么?下面是一个示例代码段,它使用
call
方法将
this
关键字显式绑定到一个对象。对该代码的哪些理论添加会改变该代码的值?当硬绑定
this
关键字时,我们要保护代码不受哪些具体问题的影响

function foo(){
  console.log(this.bar); // outputs: 9
}

var obj = {
  bar: 9
};

foo.call(obj);

一般来说,
这个
没有“显式”绑定。
的值根据调用的性质在调用函数时确定。这与函数“诞生”的环境无关

通过对象属性查找发现函数引用后调用函数时,如:

obj.someFunction();
然后所涉及的对象引用(
obj
,如上)将是该函数特定调用中的
this
的值。但是,函数引用可以轻松复制到另一个对象:

var otherObj = { someFunction: obj.someFunction };
otherObj.someFunction();
现在,
this
(在该特定调用中)的值将是对
otherObj
的引用,而不是
obj

如果将对函数的引用复制到普通变量:

var func = obj.someFunction;

func();
该调用中的
this
的值将是对
窗口的引用,或者如果代码恰好处于“严格”上下文中,则
未定义的

通过所有这些,请注意,函数最初可能在对象文本中声明为属性值,这一事实与调用中最终成为
this
的值无关

创建显式“绑定”的一种方法是利用每个函数实例可用的内置
.call()
.apply()
方法:

function whatever() { /* ... */ }

var objWhatever = function() {
  whatever.call(obj);
};
该设置明确地强制在调用函数
which()
时将对
obj
的引用用作
this
的值。您还可以使用内置的(在现代环境中)
.bind()
函数来创建这样一个“绑定”函数:

var objWhatever = whatever.bind(obj);

我个人会犹豫是否将其称为“绑定”函数,因为在封面下,它只是通过
.call()
进行的显式调用,但我并不太担心术语

正如Pointy所提到的
this
的值,或者上下文取决于函数的调用方式,本文很好地解释了它的工作原理。

添加此代码会覆盖“显式”绑定,
this
关键字现在返回
8
,这是“隐式”绑定的结果由
otherObj
对象创建的绑定。在该对象的空间中调用该函数

var otherObj = {
  foo: foo,
  bar: 8
};
otherObj.foo();
进一步添加此代码,由于函数是在全局空间中调用的,没有任何修饰,“隐式”绑定被“默认”绑定覆盖,该绑定返回全局
bar
变量,结果为
7

var secondObj = otherObj.foo;
var bar = 7;
secondObj();
在使用
call
方法调用函数之前添加此代码,将导致将
this
关键字锁定到
secondObj
对象,并产生
6
的输出

var thirdObj = {
  bar: 6
};

var foo = foo.bind(thirdObj);

“一般来说,这没有“明确的”约束。”你能详细说明这一点吗?“你是什么意思?”Sul穆i只是这样——不像java、C++、C语言这样的语言,任何特定的函数和任何特定的对象之间都没有内在的关系。我猜你是说如果这一关系可能丢失,它就不是真正的“明确”。是吗?@shmuli right-在表达式中使用
function
关键字创建函数时,结果只是一个简单的对象引用(指向新函数)。将引用指定给对象属性这一事实实际上并不具有长期重要性。
this
的值取决于函数的调用方式。调用函数有多种方法,因此,
this
获取其值的方法也有多种。MDN文档对此进行了详细解释:。一个函数可以通过
.bind()
显式绑定,在这种情况下,
这个
的值再也不能更改了。@FelixKling谢谢,但不是我真正想问的。那么我想我不明白你在问什么。@FelixKling我不是在问
这个
如何获得其值的多种方法。相反,我要问的是,在使用
call
方法时,定义和保留
this
关键字值的“安全性”。我的问题是,由于
this
关键字的众多规则之一,该值何时会被替换。如果我理解正确,那么如果函数已经通过
.bind
绑定到特定的
this
值,
,则调用(obj)
不会有任何效果(即,
不会设置为
obj
)。