当你通过“这个”作为参数[复制]当你通过“这个”作为参数[复制](When you pass 

2019-05-10 11:08发布

这个问题已经在这里有一个答案:

  • 如何将“this”关键字的工作? 23个回答

我想了解this ,而且它在这里混淆了我一下:

var randomFunction = function(callback) {
    var data = 10;
    callback(data);
};

var obj = {
    initialData:  20,
    sumData: function(data) {
        var sum = this.initialData + data;
        console.log(sum);
    },
    prepareRandomFunction: function() {
        randomFunction(this.sumData.bind(this));
    }
};

obj.prepareRandomFunction();

this设计来为自己在那里的代码首先呈现? 举例来说,在我的例子中,我成功地用它来指obj ,也结合了功能obj ,但由于this被作为回调函数传递,什么是被设置为阻止它randomFunction (即什么是从停止它从字面上传递“this.sumData.bind(本)”,让this被设置为randomFunction时,它会从那里叫)?

我努力学习一个小白。 谢谢。

更新我不完全问这通常是如何工作的(我不认为)。 我主要想知道为什么this被设置在那里我把它定义为我的论点randomFunction调用,而不是其中callback被称为内randomFunction 。 我可能是错的,但如果我是交换this.sumData.bind(this)callback(data) ,我现在有,我想我会得到不同的结果。 那是因为callback是一个参考this.sumData.bind(this) ,当它被首先定义(并在thisobj )?


我想我已经通过这个场景,了解到this时候它的执行设置。 它不是通过作为参数来当参数被称为上下行以后设置。

Answer 1:

this函数调用中被按照功能是如何被调用设置。 有迹象表明,六个主要途径this被设定。

  1. 正常的函数调用:在正常的函数调用,如foo() this被设置为全局对象(这是window的浏览器),或者undefined (在Javascript的严格模式)。

  2. 方法调用:如果一个方法被称为诸如obj.foo()this被设置为obj在函数内。

  3. 。适用()或.CALL():如果.apply().call()被使用,然后this根据什么被传递到被设置.apply().call() 例如,你可以做foo.call(myObj) ,并导致this设置为myObj的内部foo()为特定的函数调用。

  4. 使用新:如果你调用一个函数newnew foo()然后创建一个新的对象,并在构造函数foo调用与this设置为新创建的对象。

  5. 使用.bind():当使用.bind()一个新的存根函数是从内部使用的是调用返回.apply()来设置this指针传递给.bind() 仅供参考,这是不是一个真正的不同情况,因为.bind()可以实现.apply()

  6. 使用ES6脂肪Arrow功能通过在ES6 +箭头语法定义功能将当前词汇值绑定this给它。 所以,不管功能如何在其他地方调用, this值将被解释该值设置this有定义的功能时。 这是比所有其他函数调用完全不同。

有排序第七的方法,通过一个回调函数 ,但它不是真正的自己的方案,而是调用回调函数使用上述方案中的一种,并决定价值来决定this将是回调时被调用。 您要咨询无论是文档或代码,调用函数或测试它自己来决定什么this会在回调中被设置为。


什么是重要的Javascript理解的是,在Javascript中的每一个函数或方法调用设置了一个新值this 。 而且,该值设置由函数如何调用确定。

所以,如果你传递一个方法,一个普通的回调,该方法不会默认情况下,获取尽可能称为obj.method()因此不会有正确的价值this一套吧。 您可以使用.bind()来解决这个问题。

这也是有用的知道一些回调函数(如DOM事件处理程序)被调用的特定值this是通过调用回调函数的基础设置。 在内部,它们都使用.call().apply()所以这不是一个新的规则,而是一个需要注意的。 该“契约”的一个回调函数可能包括如何进行设置的值this 。 如果没有明确设置的值, this ,那么它会根据规则1#设置。

在ES6,经由箭头函数调用的函数,维持的当前词汇值this 。 这里的阵列功能保持词汇的例子this从MDN :

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| properly refers to the person object
  }, 1000);
}

var p = new Person();

您的示例obj.prepareRandomFunction(); 是规则#2的上方, this将被设置为obj

您的示例randomFunction(this.sumData.bind(this))是规则#1的上方,从而thisrandomFunction将被设置为全局对象或undefined (如果在严格模式)。

由于randomFunction正在呼叫它本身使用的回调函数.bind()则的值this时它被称为将被设置到的值的回调函数内this传递给.bind()this.sumData.bind(this) ,经由上述规则#5。 .bind()实际上创建了一个新的功能,谁的工作是调用原来的功能后再进行设定的自定义值this


下面是关于该主题的其他几个引用:

如何避免“本”指的DOM元素,并参照对象

更好地理解这个

如何将“this”关键字的工作?


请注意,在使用的.apply().call().bind()您可以创建一个有些奇怪的东西各种各样,有时是非常有用的东西,不可能在像C ++来完成。 你可以使用任何函数或方法在世界上并调用它,好像它是一些其他对象的方法。

例如,这通常被用来使在该项目的副本arguments对象到一个数组:

var args = Array.prototype.slice.call(arguments, 0);

或类似的:

var args = [].slice.call(arguments, 0);

这需要阵列的.slice()方法并调用它,而是用一个参数对象作为其供给this指针。 的arguments对象(虽然不是一个实际的阵列),具有使刚好足够的阵列一样的功能.slice()方法可以在其上操作,并且它最终使的副本arguments物品进入其然后可被操作上的实际阵列直接与真正的数组操作。 这种类型的欺骗,不能不管三七二十一完成。 如果阵列.slice()方法依赖于其他阵列方法中不存在对arguments对象,那么这招是行不通的,但是因为它仅依赖于[].length ,这两者的arguments对象具有,它不实际工作。

所以,这一招可以用“借”从任何对象的方法,并将其作为长期应用到另一个对象,你是把它们应用到任何支持的方法或该方法实际使用属性的对象。 这不是在C做++,因为方法和属性是“硬约束”在编译时间(++必将在编译时设立了专门v表转位置C甚至是虚拟的方法),但可以在JavaScript中很容易做到,因为性质和方法,在现场通过运行时的实际名称,以便包含正确的属性和方法将与这些操作的任何方法,任何工作对象抬头。



Answer 2:

一步步。

1) this内部prepareRandomFunctionobj

obj.prepareRandomFunction()

2) randomFunction取一个函数:

randomFunction(this.sumData);

3)函数被调用:

callback(data);

通知callback被不带一个点,这意味着它具有用于没有价值this ,这意味着this是全局对象(或undefined严格模式)。

4) sumData被调用:

var sum = this.initialData + data;

this是全局对象, initialData不存在,您添加undefineddata 。 意想不到的效果。

解决方法:绑定this永久:

randomFunction(this.sumData.bind(this));

4) sumData运行时, thisobjobj.initialData20 。 有用。



Answer 3:

这是专为自己设置它在代码首先呈现?

不,这是通过一个函数是如何调用或通过使用绑定设置。

举例来说,在我的例子中,我成功地用它来指OBJ

由于该功能是使用所谓的:

obj.prepareRandomFunction();

其中规定在obj功能。

并且还结合了功能OBJ

在:

var obj = {
  ...
  prepareRandomFunction: function() {
      randomFunction(this.sumData.bind(this));
  }
};

因为prepareRandomFunction被称为所有与obj这一点 ,那么内obj.sumData这个值设置为OBJ,并调用randomFunction有效地解析为:

  randomFunction(obj.sumData.bind(obj));

但因为这是被作为一个回调函数传递,什么是被设定为randomFunction停止它

您设定这样一个事实在通话OBJ。 如果你想randomFunction,您需要将其设置为。 randomFunction这个没有内在价值,它是由该函数的调用(或使用绑定的)设置。

(即什么是从字面上传递“this.sumData.bind(本)”,因此,这是设置为randomFunction停止它)?

因为不是randomFunction时执行该代码。

所以:

obj.prepareRandomFunction();

一套到obj,然后做(用OBJ更换这就要求prepareRandomFunction:

randomFunction(obj.sumData.bind(obj));

randomFunction, 并没有被设置成默认为全局对象(无关真的,因为它是这里没有使用)。 然后:

var randomFunction = function(callback) {
    var data = 10;
    callback(data);
};

与值10创建一个局部变量的数据 ,然后用它的一套来的obj调用sumData和传递数据的价值。 然后:

sumData: function(data) {
    var sum = this.initialData + data;
    console.log(sum);
},

而且由于OBJ,分配有效解决到:

  var sum = obj.initialData + 10;

这是30。



Answer 4:

这是一种自 - 对象的参考。 运营商,宣布其作为对象 - - 当你,或者通过使用新创建对象文本或
通过调用JS的内置-in的之一,这将要被分配给它。
但随着JS的作用域是动态的,而不是非 - 短暂的,你通常不能依靠这个太多了 - 对象。 这就是为什么你经常看到的结构,如oThis:本或VARØ



文章来源: When you pass 'this' as an argument [duplicate]