为什么我们需要Function.prototype.call,在这里我们可以通过在javascript中将函数附加到对象来实现同样的功能

为什么我们需要Function.prototype.call,在这里我们可以通过在javascript中将函数附加到对象来实现同样的功能,javascript,jquery,ecmascript-6,Javascript,Jquery,Ecmascript 6,我已经看到了call、apply和bind的这些示例 var-fruit={name:'草莓'} 功能展示详情(尺寸、价格){ console.log(this.name+''+size+':$'+price+'/lb') } 展示细节。涂抹(水果,['small',10]) //草莓小号:10美元/磅 showDetails.call(水果,'small',10) //草莓小号:10美元/磅 var绑定=showDetails.bind(水果,'small',10) 绑定() //草莓小号:

我已经看到了call、apply和bind的这些示例

var-fruit={name:'草莓'}
功能展示详情(尺寸、价格){
console.log(this.name+''+size+':$'+price+'/lb')
}
展示细节。涂抹(水果,['small',10])
//草莓小号:10美元/磅
showDetails.call(水果,'small',10)
//草莓小号:10美元/磅
var绑定=showDetails.bind(水果,'small',10)
绑定()
//草莓小号:10美元/磅
展示细节。绑定(水果,'小',10)()
//草莓小号:每磅10美元
  • 我们需要(想要)
    调用
    应用
    ,因为它们比备选方案简单得多(显然取决于用例)
  • 我们需要
    调用
    应用
    ,因为替代方案不适用于我们无法分配属性(冻结或密封)的对象
  • 在函数求值过程中,当方法不应该是对象的属性时,我们需要
    调用
    应用
  • 我们还需要
    apply
    ,因为
    call
    无法处理动态数量的参数(忽略新的扩展语法),请参阅。而
    bind
    是一种完全不同的野兽,请参见。

    • 我们需要(想要)
      调用
      应用
      ,因为它们比备选方案简单得多(显然取决于用例)
    • 我们需要
      调用
      应用
      ,因为替代方案不适用于我们无法分配属性(冻结或密封)的对象
    • 在函数求值过程中,当方法不应该是对象的属性时,我们需要
      调用
      应用
    我们还需要
    apply
    ,因为
    call
    无法处理动态数量的参数(忽略新的扩展语法),请参阅。而
    bind
    是一种完全不同的野兽,请参见

    我们可以通过在javascript中向对象添加函数来实现同样的目的

    根据你的例子,你是对的。但在javascript中,我们需要将函数作为回调传递给浏览器事件循环队列以执行异步。在这种情况下,物体将丢失。检查下面的示例

    var fruit = { name: 'Strawberry' };
    function showDetails(size, price) {
      console.log(this.name + ' ' + size + ': $' + price + '/lb')
    }
    fruit.show =showDetails;
    
    setTimeout(fruit.show, 100);
    
    这里的输出是未定义的,所以要附加参数和上下文对象,我们需要“绑定”

    现在,我们可以使上述工作与

    setTimeout(水果.显示.绑定(水果,大小,价格),100)

    apply/call的用法是通过动态提供函数的上下文和参数来执行函数。检查呼叫的以下用法

    var Array.protoype.forEach = function(cb /*, thisArg*/){
      var T;
      if (arguments.length > 1) {
          T = arguments[1];
        }
      for(var i =0; i<this.length; i++){
        cb.call(T, this[i], i, this);
      }
    }
    
    var Array.prototype.forEach=函数(cb/*,thisArg*/){
    变量T;
    如果(arguments.length>1){
    T=参数[1];
    }
    对于(var i=0;i
    我们可以通过在javascript中向对象添加函数来实现同样的目的

    根据您的示例,您是对的。但在javascript中,我们需要将函数作为回调传递给浏览器事件循环队列以执行异步。在这种情况下,对象将丢失。请检查下面的示例

    var fruit = { name: 'Strawberry' };
    function showDetails(size, price) {
      console.log(this.name + ' ' + size + ': $' + price + '/lb')
    }
    fruit.show =showDetails;
    
    setTimeout(fruit.show, 100);
    
    这里的输出是未定义的,所以要附加参数和上下文对象,我们需要“绑定”

    现在,我们可以使上述工作与

    setTimeout(水果.展示.绑定(水果,大小,价格),100);

    apply/call的用法是通过动态提供函数的上下文和参数来执行函数。请检查调用的后续用法

    var Array.protoype.forEach = function(cb /*, thisArg*/){
      var T;
      if (arguments.length > 1) {
          T = arguments[1];
        }
      for(var i =0; i<this.length; i++){
        cb.call(T, this[i], i, this);
      }
    }
    
    var Array.prototype.forEach=函数(cb/*,thisArg*/){
    变量T;
    如果(arguments.length>1){
    T=参数[1];
    }
    
    对于(var i=0;i事实上,在许多情况下,在对象上定义方法是可行的选择。但是,有时它不是一个选项:

    1.对象不允许定义方法:
    “严格使用”;
    函数showDetails(){console.log(this.name);}
    var obj=Object.seal({name:'草莓'});
    showDetails.call(obj);//草莓
    
    obj.showDetails=showDetails;//失败
    事实上,在许多情况下,在对象上定义方法是可行的选择。但是,有时它不是一个选项:

    1.对象不允许定义方法:
    “严格使用”;
    函数showDetails(){console.log(this.name);}
    var obj=Object.seal({name:'草莓'});
    showDetails.call(obj);//草莓
    
    obj.showDetails=showDetails;//失败
    如果
    fruit
    已经有一个名为“show”的属性怎么办?每当你想这样做的时候,总是要向一个对象添加一个属性,这将是一个混乱。我们可以用
    hasOwnProperties
    进行检查,对吗?Pointy说了什么。甚至可能是对象被密封了,然后你的选择就不被允许了。@user8208248你更愿意使用
    。调用
    或检查
    hasOwnProperties
    对于所有内容?对象也可能被冻结
    fruit=object.freeze({name:'草莓'})
    如果
    fruit
    已经有一个名为“show”的属性,该怎么办?每当你想这样做的时候,总是要向一个对象添加一个属性,这将是一个混乱。我们可以用
    hasOwnProperties
    进行检查,对吗?Pointy说了什么。甚至可能是对象被密封了,然后你的选择就不被允许了。@user8208248你更愿意使用
    。调用
    或检查
    hasOwnProperties
    对于所有内容?对象也可能被冻结
    fruit=object.freeze({name:'草莓'})