Javascript 使用 JS .call() 方法的原因?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9001830/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 08:21:45  来源:igfitidea点击:

The reason to use JS .call() method?

javascriptfunctionmethodsthis

提问by Green

I'm interested what's the reason to have call() method in JS. It seems it duplicates usual method of calling this.

我对在 JS 中使用 call() 方法的原因很感兴趣。它似乎重复了通常的调用方法this

For example, I have a code with call().

例如,我有一个带有 call() 的代码。

var obj = {
    objType: "Dog"
}

f = function(did_what, what) {
    alert(this.objType + " " + did_what + " " + what);
}

f.call(obj, "ate", "food");

The output is "Dog ate food". But the same result I can get assigning the function to the object.

输出是“Dog ate food”。但是同样的结果我可以将函数分配给对象。

var obj = {
    objType: "Dog"
}

f = function(did_what, what) {
    alert(this.objType + " " + did_what + " " + what);
}

obj.a = f;
obj.a("ate", "food");

The result is the same. But this way is more understandable and convenient to use. Why call() is needed?

结果是一样的。但是这种方式更容易理解,使用起来也方便。为什么需要 call() ?

回答by David Hellsing

callis used when you want to control the scope that will be used in the function called. You might want the thiskeyword to be something else than the scope you assigned the function to, in those cases you can use callor applyto call the function with your own scope.

call当您想要控制将在调用的函数中使用的范围时使用。您可能希望this关键字不是您为函数分配的范围,在这些情况下,您可以使用callapply使用您自己的范围调用函数。

F.ex, it also allows you to call utility methods outside the scope, like when using "private" functions:

F.ex,它还允许您在范围之外调用实用程序方法,例如使用“私有”函数时:

var obj = (function() {
    var privateFn = function() {
        alert(this.id);
    }
    return {
        id: 123,
        publicFn: function() {
            privateFn.call(this);
        }
    };
}());

obj.publicFn();

In the example above, privateFnis not exposed in objbut it can still be constructed as if it was a part of the public scope (using thisin the same way).

在上面的例子中,privateFn没有暴露在,obj但它仍然可以被构造为好像它是公共范围的一部分(this以相同的方式使用)。

回答by Robert Rocha

2017 Update

2017年更新

All functions by way of Function.prototype have the .callmethod. The reason to use .call()is to specify what the variable "this" refers to.

所有通过 Function.prototype 的函数都有.call方法。使用的原因.call()是指定变量“ this”指的是什么。

MDN specifies:

MDN 规定:

The call()method calls a function with a given this value and arguments provided individually.

call()方法使用给定的 this 值和单独提供的参数调用函数。

Consider the following:

考虑以下:

function x() {
    return this;
}

x()

In strict mode x()returns undefinedin non strict mode it returns the Global object, Windowin a browser context.

在严格模式下x()返回undefined在非严格模式下,它返回全局对象,Window在浏览器环境。

Example with .call()we tell it what "this" refers to:

例如,.call()我们告诉它“ this”指的是什么:

function x() {
    return this;
}

var obj = {
    myName      : 'Robert',
    myLocation  : 'Earth'
}

x.call(obj);

Result: {myName: "Robert", myLocation: "Earth"}. In the above example we are specifying the objobject as the value of thisinside the function x()

结果:{myName: "Robert", myLocation: "Earth"}。在上面的例子中,我们将obj对象指定为this函数内部的值x()

It can be used to emulate inheritance in OOP.

它可用于模拟 OOP 中的继承。

Example:

例子:

var Robert = {
    name: "Robert Rocha",
    age: 12,
    height: "5,1",
    sex: "male",
    describe: function() {
        return "This is me " + this.name + " " + this.age + " " + this.height + " " + this.sex;
    }
};

Lets say that the above is a master object(prototype) and you want to inherit the function describein another object:

假设上面是一个主对象(原型),并且您想describe在另一个对象中继承该功能:

var Richard = {
    name: "Richard Sash",
    age: 25,
    height: "6,4",
    sex: "male",
}

The Richardobject does not have the describe function and you want to simply inherit ,so to speak, the function. You would do it like so:

Richard对象没有描述功能,您只想继承,可以说,该功能。你会这样做:

console.log( Robert.describe.call( Richard ) );

Output: This is me Richard Sash 25 6,4 male

输出: This is me Richard Sash 25 6,4 male

回答by Dennis

You would probably use the second way in your example, but sometimes you want to use one object's functions on another object. An example would be using Arraymethods on Array-like objects like NodeLists

您可能会在示例中使用第二种方式,但有时您想在另一个对象上使用一个对象的函数。一个例子是Array在类似数组的对象上使用方法,比如NodeLists

var el = document.getElementById("foo");
[].forEach.call(el.children, function(child, index) {
    //Iterate over an element's children, performing an action on each one
});

回答by Rob Agar

It's to do with the concept of a first class function. Basically languages like Javascript allow you to treat functions as things their own right. Functions can be stored in variables or passed to other functions.

这与first class function的概念有关。基本上,像 Javascript 这样的语言允许您将函数视为自己的权利。函数可以存储在变量中或传递给其他函数。

call()provides a way to execute a free standing function not attached to any other object.

call()提供了一种执行不附加到任何其他对象的独立功能的方法。