gpt4 book ai didi

javascript - 当您将 'this' 作为参数传递时?

转载 作者:数据小太阳 更新时间:2023-10-29 04:54:21 24 4
gpt4 key购买 nike

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





How does the "this" keyword work?

(21 个回答)


6年前关闭。




我正在尝试了解 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并将函数绑定(bind)到 obj ,但由于 this正在作为回调函数传递,是什么阻止它被设置为 randomFunction (即是什么阻止它从字面上传递“this.sumData.bind(this)”,以便 this 在从那里被调用时设置为 randomFunction)?
更新
我并不是在问这通常是如何工作的(我不认为)。我主要是想知道为什么 this在我将其定义为我的 randomFunction 的参数的地方被设置打电话,而不是在哪里 callbackrandomFunction 内被调用.
我可能是错的,但如果我要交换 this.sumData.bind(this)callback(data)我目前拥有的我认为我会得到不同的结果。是不是因为 callback是对 this.sumData.bind(this) 的引用它是什么时候第一次定义的(在哪里 thisobj )?

我想我已经通过这个场景了解到 this执行时设置。它不会作为参数传递,以便稍后在该参数被调用时进行设置。

最佳答案

this在函数调用内部根据函数的调用方式设置。 this主要有六种方式设置。

  • 普通函数调用:在正常的函数调用中,例如 foo() , this设置为全局对象(浏览器中的 window 或 nodejs 中的 global)或 undefined (在 JavaScript 的严格模式下)。
  • 方法调用:如果一个方法被调用,例如 obj.foo()其中方法foo是使用 function 的普通方法声明关键字或对 class 使用常规方法声明语法,然后 this设置为 obj函数内部。
  • .apply() 或 .call(): .apply().call()被使用,然后 this根据传递给 .apply() 的内容设置或 .call() .例如,你可以做 foo.call(myObj)并导致 this设置为 myObj内部 foo()对于那个特定的函数调用。
  • 使用新的:如果您使用 new 调用函数如 new foo() ,然后创建一个新对象和构造函数 foothis 调用设置为新创建的对象。
  • 使用 .bind(): 使用时 .bind()从内部使用 .apply() 的调用返回一个新的 stub 函数设置 this传递给 .bind() 的指针.仅供引用,这并不是真正的不同情况,因为 .bind()可以通过 .apply() 实现.
  • 使用 ES6胖箭头函数 在 ES6+ 中通过箭头语法定义一个函数将绑定(bind)当前的词法值 this到它。因此,无论在其他地方如何调用该函数(使用之前的任何调用方式),this value 将由解释器设置为值 this在定义函数时有。这与所有其他函数调用完全不同。

  • 有第七种方法,通过 回调函数 ,但它实际上并不是它自己的方案,而是调用回调的函数使用上述方案之一,这决定了 this 的值。将在调用回调时。您必须查阅文档或调用函数的代码或自行测试以确定是什么 this将在回调中设置为。

    在 JavaScript 中需要理解的重要一点是 JavaScript 中的每个函数或方法调用都会为 this 设置一个新值。 .并且,设置哪个值取决于函数的调用方式。
    因此,如果您将方法作为普通回调传递,默认情况下该方法不会被调用为 obj.method()因此不会有 this 的正确值设置它。您可以使用 .bind()解决这个问题。
    了解某些回调函数(例如 DOM 事件处理程序)使用特定值 this 调用也很有用。由调用回调函数的基础设施设置。在内部,他们都使用 .call().apply()所以这不是一个新规则,而是需要注意的事情。回调函数的“契约”可能包括它如何设置 this 的值。 .如果没有明确设置 this的值,那么它将根据规则 #1 进行设置。
    在 ES6 中,通过箭头函数调用函数,维护当前词法值 this .这是维护词法 this 的数组函数的示例 from 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 所以 this内部 randomFunction将设置为全局对象或 undefined (如果在严格模式下)。
    由于 randomFunction 正在调用一个回调函数,该函数本身使用了 .bind() ,那么 this 的值回调函数内部调用时会被设置为 this的值传递给 .bind()this.sumData.bind(this)就像上面的第 5 条规则一样。 .bind()实际上创建了一个新函数,它的工作是在设置自定义值 this 之后调用原始函数。 .

    以下是有关该主题的其他一些引用资料:
    How to avoid "this" refering to the DOM element, and refer to the object
    A better understanding of this
    How does the "this" keyword work?

    请注意,使用 .apply().call().bind() ,您可以创建各种有点奇怪的东西,有时甚至是非常有用的东西,而这些东西在 C++ 之类的东西中是永远无法完成的。 .您可以使用世界上的任何函数或方法,并像调用其他对象的方法一样调用它。
    例如,这通常用于复制 arguments 中的项目。对象到数组中:
    var args = Array.prototype.slice.call(arguments, 0);
    或类似:
    var args = [].slice.call(arguments, 0);
    这需要数组的 .slice()方法并调用它,但为它提供了一个参数对象作为 this指针。 arguments对象(虽然不是实际的数组),具有足够的类似数组的功能, .slice()方法可以对其进行操作,它最终会复制 arguments items 到一个实际数组中,然后可以直接使用实际数组操作对其进行操作。这种诡计不能随意完成。如果数组 .slice()方法依赖于 arguments 上不存在的其他数组方法对象,那么这个技巧是行不通的,但因为它只依赖于 [].length ,其中 arguments对象有,它确实有效。
    因此,这个技巧可用于从任何对象“借用”方法并将它们应用到另一个对象,只要您应用它们的对象支持该方法实际使用的任何方法或属性。这不能在 C++ 中完成,因为方法和属性在编译时是“硬绑定(bind)”的(甚至 C++ 中的虚拟方法都绑定(bind)到在编译时建立的特定 v-table 位置),但可以在 JavaScript 中轻松完成,因为属性和方法在运行时通过它们的实际名称实时查找,因此任何包含正确属性和方法的对象都将与对这些进行操作的任何方法一起使用。

    关于javascript - 当您将 'this' 作为参数传递时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28016664/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com