既然可以将目标对象作为参数传递,为什么还要使用 apply() 或 call() 呢?

Why use apply() or call() when you can pass the target object as a parameter?

我了解使用 apply() 和 call() 的用例。您基本上可以从另一个对象调用函数,并指定 this 绑定。这当然只有在所述函数使用 this 关键字时才有意义。

我不明白的是,为什么要在一个对象中创建一个函数,然后决定要通过更改它来在其他地方重用它?对我来说,这听起来像是第一个对象中的函数有意义,而不是重构函数使其独立存在,程序员决定将它留在那里并用 apply/call.

调用它

从那个对象中取出那个函数,把它放在其他地方,让它可以被不同的对象使用,通过让它把那个目标对象作为一个显式参数,对我来说更有意义.

我是不是漏掉了什么?

那么您更想要 String.toUpperCase("aa") 而不是 "aa".toUpperCase()

这基本上意味着您投票反对任何访问它们所调用对象的实例方法。

It would make more sense to me to take that function out of that object, and put it somewhere else where it's clearly visible that it can be used by different objects, by having it take that target object as an explicit parameter.

在我看来,这将是一个巨大的倒退,并导致嵌套函数调用一团糟:

而不是例如

'abcdef'.toUpperCase().split('').join('.')

你必须做

String.join(
  String.split(
    String.toUpperCase('abcdef'),
    ''
  ),
  '-'
);

我可以举一个有用的例子。很久以前,在 ES6 之前,实现 javascript 继承有点复杂——有两种类型的继承。所以为了创建一个 class 并用另一个 class 继承它,你必须做这样的事情:

function Parent(){
   this.parentParam="parentParam";
};

Parent.prototype.logThisContext = function(){ 
   console.log(this);
};

function Child(){
   Parent.call(this);
};

Child.prototype = Object.create(Parent.prototype);

现在如果你想覆盖父logThisContext函数,你应该这样写:

Child.prototype.logThisContext = function(){
   // calling base functionality
   Parent.prototype.logThisContext.call(this);
   // add child functionality
   console.log("overriden behavior");
}

如果您不使用 this 调用 logThisContext,您将记录原型本身而不是具体实例。

您可以尝试删除 this 的调用的代码,您会自己看到不同之处:)

编辑:我不确定这是否能给您想要的答案,但是 logThisContext 从技术上讲是您在答案中提到的对象内部函数。