何时以及为何使用“致电”和“申请”?

RON*_*ONE 2 javascript prototype-programming

首先我知道了 apply() 和 call() 之间的区别。

function theFunction(name, profession) {
    alert("My name is " + name + " and I am a " + profession + ".");
}

theFunction("John", "fireman");
theFunction.apply(undefined, ["Susan", "school teacher"]); // This call be called theFunction("Susan", "school teacher");, why use apply
theFunction.call(undefined, "Claude", "mathematician"); // This call be called theFunction("Claude", "mathematician");, why use call 
Run Code Online (Sandbox Code Playgroud)

从上面的代码来看,3个函数调用都显示了警报消息。

  1. 与普通函数调用相比,使用 apply 和 call 的优点/缺点是什么,什么时候适合使用 apply/call,请澄清一下。

  2. 还有一件事,如果该函数是基于原型的函数怎么办:

Function.prototype.theFunction = 函数(名称, 职业) {

    alert("My name is " + name + " and I am a " + profession + ".");
}
Run Code Online (Sandbox Code Playgroud)

那么如何使用 apply 或 call 来调用这个函数呢?我尝试了这样的方法:

theFunction.apply(undefined, ["Susan", "school teacher"]); 
theFunction.call(undefined, "Claude", "mathematician"); 
Run Code Online (Sandbox Code Playgroud)

但导致错误。“参考错误:函数未定义”

Meh*_*ami 5

正如您所说,您似乎已经知道这些函数的功能apply()call()实际用途,但就其用途而言,我想说它们主要用于当您想为您提供function自己的特定对象(作为其this值)时在其背景下。

这两者最流行的用途之一是处理类似数组的对象,例如arguments函数中的对象:

function(){
    //let's say you want to remove the first parameter from the arguments object

    //you can make sure that
    console.log(arguments instanceof Array);//false

    //as you see arguments is not an actual array object but it is something similar
    //and you want slice out its value
    var myparams = Array.prototype.slice.call(arguments, 1);

    //here you have myparams without your first argument

    console.log(arguments);
}
Run Code Online (Sandbox Code Playgroud)

让我们再举一个例子。假设我们有一个独立的函数,例如:

function getName(){
    console.log(this.name);
}
Run Code Online (Sandbox Code Playgroud)

现在你可以将它用于任何类型的具有name属性的 JavaScript 对象:

var myInfo = {
    name: 'SAM'
};
Run Code Online (Sandbox Code Playgroud)

现在如果你这样做:

getName.call(myInfo);
Run Code Online (Sandbox Code Playgroud)

它的作用是打印出name属性,或者您可以在函数本身上尝试它:

getName.call(getName);
Run Code Online (Sandbox Code Playgroud)

"getName"这将在控制台中打印出函数的名称 ( )。

但与我的第一个示例类似,它通常在您想要使用不在对象原型链中的函数时使用。另一个例子可能是:

//let's say you have an array
var myArray = [1 , 2];
//now if you use its toString function
console.log(myArray.toString());//output: "1,2"

//But you can use the Object toString funcion
//which is mostly useful for type checking
console.log(Object.prototype.toString.call(myArray));//output: "[object Array]"
Run Code Online (Sandbox Code Playgroud)