简体   繁体   English

call()在其自己的上下文中的函数

[英]call() a function within its own context

 var f = function() { this.x = 5; (function() { this.x = 3; })(); console.log(this.x); }; f.call(f); f(); f.call(); 

Running var f as f.call(f) outputs 5 . var f作为f.call(f)输出5 When running it as f() or f.call() outputs 3 . 当以f()f.call()输出3时运行它。

What happens in each case? 每种情况都会发生什么? What does the inner function's this refer to? 什么内在功能的this是指什么?

First Case: 第一个案例:

In the first you are calling the function. 在第一个你正在调用该函数。 And inside the function the function itself ie f is set as this . 在函数内部,函数本身即f被设置this So in first example this.x = 5; 所以在第一个例子中this.x = 5; sets the property x on the function. 在函数上设置属性x

When the inner function is called this refers to window object so this.x = 3; 当调用内部函数时, this指的是window对象,因此this.x = 3; changes the x property of window object. 更改window对象的x属性。

When it logs console.log(this.x); 当它记录console.log(this.x); here the same property x which was set as property of function is logged. 这里记录了设置为函数属性的相同属性x

Second Case: 第二种情况:

In the second example this inside the outer function refers to window so when this.x = 3; 在第二个例子中, this外部函数内部是指window所以当this.x = 3; is evaluated the window.x becomes 3 . 评估window.x变为3 As this refers to window in outer function so console.log(this.x); 因为this指的是外部函数中的window所以console.log(this.x); logs window.x which is 3 记录window.x ,即3

Conclusion: 结论:

The conclusion of the whole discussion is that if no argument is passed to call() then automatically window object is binded. 整个讨论的结论是,如果没有参数传递给call()那么自动window对象被绑定。 According to MDN MDN称

thisArg thisArg

Optional. 可选的。 The value of this provided for the call to a function. 为函数调用提供的值。 Note that this may not be the actual value seen by the method: if the method is a function in non-strict mode, null and undefined will be replaced with the global object and primitive values will be converted to objects. 请注意,这可能不是方法看到的实际值:如果方法是非严格模式下的函数,则null和undefined将替换为全局对象,并且原始值将转换为对象。

See the below snippet. 请参阅以下代码段。

 function foo(){ console.log(this); } foo.call(foo); //foo function foo.call(); //window object 

If there is no specific context, this will be window . 如果没有特定的上下文, this将是window Your inner function always runs without a context, so it'll set window.x to 3. If you call f() , it will also run with this being window therefore logging the 3. 你的内部函数总是在没有上下文的情况下运行,所以它将window.x设置为3.如果你调用f() ,它也会运行this window因此记录3。

If you however do f.call(f) , this will be the f function object, and it's x property will be set to 5. 但是如果你做f.call(f) ,那么this将是f函数对象,它的x属性将被设置为5。

  f.call(f)
  console.log(
    f.x, // 5
    window.x // 3
  );

I'd recommend stepping through it with the debugger if it isn't clear yet. 如果还不清楚,我建议使用调试器逐步执行它。

When you call f with a reference to itself, it sets the x property to 5 on the function and the inner anonymous function has its this referring to the window, so it sets window.x to 3. Outside the anonymous function, this still refers to the function f , so console.log(this.x) outputs 5. 当你调用f与对自身的引用,它设置x属性5功能和内部匿名函数有this指的是窗口,所以它window.x设置为3以外的匿名函数, this还是指到函数f ,所以console.log(this.x)输出5。

When you invoke f using f() or f.call() the function f and the anonymous function inside it have a this reference set to the window (the default) and so changing the value of this.x inside or outside the anonymous function affects the output result. 当您使用f()f.call()调用f时,函数f和其中的匿名函数this引用设置为window (默认值),因此在匿名函数内部或外部更改this.x的值影响输出结果。

You can see this clearly if you console.log the values of this inside the function f and inside the inner anonymous function. 如果你CONSOLE.LOG的值,你可以清楚地看到这this函数f内部和内部匿名函数内部。

 var f = function() { console.log("This inside function f:", this.toString()); this.x = 5; (function() { console.log("This inside anonymous inner function:", this.toString()); this.x = 3; })(); console.log(this.x); }; console.log("calling function x with this set to itself"); f.call(f); console.log("---------------") console.log("invoking function x with brackets ()") f(); console.log("---------------") console.log("calling function x without setting this context") f.call(); console.log("---------------") 

Further to the other answers, should you want predictable behaviour, you have at least 2 methods available to you. 除了其他答案之外,如果您想要可预测的行为,您至少可以使用2种方法。

Method 1: (closure) 方法1 :(关闭)

var f = function() {
  this.x = 5;
  var that = this;
  (function() {
    that.x = 3;
  })();
  console.log(this.x);
};

f.call(f); // 3

f(); // 3

f.call(); // 3

Method 2: (arrow function) 方法2 :(箭头功能)

var f = () => {
  this.x = 5;
  (function() {
    this.x = 3;
  })();
  console.log(this.x);
};

f.call(f); // 3

f(); // 3

f.call(); // 3

'this' keyword refers to the context object in which the current code is executing. 'this'关键字指的是当前代码正在执行的上下文对象。 Outside any function this refers to the global object. 在任何函数之外,这指的是全局对象。

By using call() , apply() functions the value of this can pass from one context to another context. 通过使用call()apply()函数,this的值可以从一个上下文传递到另一个上下文。

  • So in the 1st case [ f.call(f) ] by calling the call function and giving the first argument as f , this.x refers to 5. So answer is printed as 5. 所以在第一种情况下[ f.call(f) ]通过调用call函数并将第一个参数赋予fthis.x引用5.因此,答案打印为5。
  • 2nd case [ f() ] it is calling the function without using call function. 第二种情况[ f() ]它在不使用调用函数的情况下调用函数。 So it refers the execution context of this as 3. So it prints as 3. 因此,它是指的执行上下文this为3。因此,作为打印3。
  • In the third case [ f.call() ], inside the call function no argument is mentioned. 在第三种情况[ f.call() ]中,在调用函数内部没有提到参数。 So it refers to the global object and prints 3 as the output. 所以它引用全局对象并打印3作为输出。

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

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