javascript理解_用JavaScript理解这一点

javascript理解

介绍(Introduction)

I guess this is the most confusing concept in javascript, how to findthis (context) of a function. And the misconception is to look where the function is declared or defined. this is a binding made for each function invocation.

我猜这是javascript中最令人困惑的概念,如何找到函数的this (上下文)。 误解是看该函数的声明或定义位置。 this是对每个函数调用的绑定。

To understand this binding, we have to understand the call-site: the location in code where a function is called (not where it's declared). We must inspect the call-site to answer the question: what's this a reference to?

要了解this绑定,我们必须了解call-site :代码在代码中调用函数的位置(而不是在声明函数的位置)。 我们必须检查呼叫站点以回答问题: this是指什么?

如何使用呼叫站点找出“此”? (How to figure out “this” using call-site?)

Now we understood that, this (context) is dependent on the call-site and to find out the context javascript has some rules to decide.

现在我们了解到, this (上下文)取决于调用站点,并且要找出context javascript有一些规则可以决定。

规则1-默认绑定 (Rule 1 — Default Binding)

// function declaration
function foo() {
console.log(this.a);
}var a = 1;// call-site
foo(); // 1

The first rule which is most commonly used: standalone function invocation. We see that when foo() is called this.a is referring to global variable a Why? Because foo() is called with a plain, un-decorated function reference so this will refer to the global object.And in case of strict mode, this will be undefined and the above scenario will throw a Reference Error.

最常用的第一条规则:独立函数调用。 我们看到当foo()称为this.a引用全局变量a为什么? 因为foo()被调用,一个普通的,未修饰的函数参照所以this将是指全球object.And在严格模式的情况下 this 将是未定义的,并且上述情况将引发参考错误。

规则2 –隐式绑定 (Rule 2 — Implicit Binding)

function foo() {
console.log(this.a)
}var a = 5;var bar = {
a: 1,
foo: foo
}//call-site
bar.foo(); // 1

Second rule, here we are using a reference to call the function. In the above example if you see, the call-site uses the bar context to reference the function, so you could say that the bar object "owns" or "contains" the function reference at the time the function is called. So this will refer to object bar and output will be 1 .

第二条规则,这里我们使用引用来调用函数。 在上面的示例中,如果您看到的话,调用站点将使用bar上下文来引用该函数,因此可以说在调用函数时bar对象“拥有”或“包含”该函数引用。 因此, this将引用对象bar并且输出将为1

规则3 –隐性失落 (Rule 3 — Implicit Lost)

function foo() {
console.log(this.a)
}var a = "global";var bar = {
a: "local",
foo: foo
}var wiz = bar.foo;//call-site
wiz(); // global

In this rule there is slight confusion that even though wiz is a reference to bar.foo infact, it is just another reference to foo itself. So as we discussed from the start this depends on the call-site only and in above case which is a plain, un-decorated call and thus the default binding applies.this.a is resulting in global .

在此规则中,有一点混乱,即使wiz实际上是对bar.foo的引用,也只是对foo本身的另一个引用。 因此,正如我们从一开始就讨论的那样, this取决于呼叫站点,在上述情况下,这是一个普通的,未经修饰的呼叫,因此默认绑定适用。 this.a是导致global

规则4-显式绑定 (Rule 4 — Explicit Binding)

As you all are aware we can explicitly provide context to a function call using call, apply and bind.

众所周知,我们可以使用callapplybind为函数调用显式提供上下文。

// function declaration
function foo() {
console.log(this.a);
}var obj = {
a: "Obj reference"
};foo.call(obj); // Obj reference

In this rule, as we see the above case we are explicitly providing context for function foo using call method of functions. So this will refer to object obj as provided by call method and same applies for apply method also. But let’s take one example for bind to clear out confusions if any.

在此规则中,如我们看到的上述情况,我们使用函数的调用方法为foo显式提供上下文。 因此, this将引用调用方法提供的对象obj ,同样适用于apply方法。 但是,让我们以绑定为例,以消除混乱(如果有)。

function foo() {
console.log(this.a);
}var obj = {
a: "Obj reference"
};var bar = foo.bind(obj);
bar(); // Obj reference

In this scenario, you will be tempted to consider it as default rule but it is different because we hard binded the context of function bar using bind and after that it will not depend on its call-site actually. That is the reason it is considered as a different rule.If you know above 4 rules you can easily figure out the context of a function invocation at anytime, anyplace in your code.

在这种情况下,您很容易将其视为默认规则,但这是不同的,因为我们使用bind硬绑定了功能bar的上下文,此后它实际上并不依赖于其调用位置。 这就是将其视为不同规则的原因。 如果您了解上述4条规则,则可以随时随地轻松地在代码中找出函数调用的上下文。

箭头功能/粗箭头 (Arrow Functions/ Fat Arrow)

Now one more thing we all should know that breaks all the above rules and introduced in ES6, that are Arrow Functions a.k.a Fat Arrow.

现在,我们都应该知道另一件事,那就是打破了上述所有规则并在ES6中引入,即Arrow Functions aka Fat Arrow。

Arrow functions use context of its lexical scope. In simpler way, arrow-functions adopt the this binding from the enclosing (function or global) scope. Let’s the below example to clear out more -

箭头函数使用其词法范围的context 。 以更简单的方式,箭头函数从封闭的(函数或全局)范围采用this绑定。 让我们在下面的示例中清除更多内容-

function foo() {
// return an arrow function
return (a) => {
// `this` here is lexically adopted from `foo()`
console.log( this.a );
};
}

var obj1 = {
a: 2
};

var obj2 = {
a: 3
};

var bar = foo.call( obj1 );
bar.call( obj2 ); // 2, not 3!

So when we wrote var bar = foo.call( obj1 ); , if you see the declaration of function foo() it doesn’t involve any arrow function so according to the standard 4 rules we calledfoo with reference to object obj1 and its return function is assigned to bar . Now the next line bar.call( obj2 ); even though we are calling the return function with reference to object obj2 but it is declared as an arrow function so it will use the context of function foo which we set to object obj1 i.e Output will be 2 not 3.

因此,当我们编写var bar = foo.call( obj1 ); ,如果您看到函数foo()的声明,则其中不包含任何箭头函数,因此根据标准4规则,我们将foo引用为对象obj1并将其返回函数分配给bar 。 现在下一行bar.call( obj2 ); 即使我们引用对象obj2来调用return函数,但是它被声明为箭头函数,所以它将使用我们设置为对象obj1的函数foo的上下文,即Output将为2 not 3

概要 (Summary)

  1. To find out context orthis of a function invocation is dependent on its call-site (location where function is called).

    要了解上下文或this函数调用的是依赖于它的调用点(位置在那里函数被调用)。

  2. To figure out context from call-site, we have some standard rules which we discussed.

    为了弄清呼叫站点的上下文,我们讨论了一些标准规则。
  3. Arrow Functions doesn’t follow any standard rule,they adopt the this binding from the enclosing (function or global) scope.

    Arrow Functions不遵循任何标准规则,它们从封闭的(函数或全局)范围采用this绑定。

翻译自: https://medium.com/swlh/understanding-this-in-javascript-166164e7fa2b

javascript理解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值