【问题标题】:Call/Bind/Apply vs prototype调用/绑定/应用与原型
【发布时间】:2016-06-17 03:21:42
【问题描述】:

在以下代码中:

function User(name) {
    this.name = name;
}

var user = new User('Jason Bourne');

User.prototype.sayHi = function() {
    return 'Hi ' + this.name;
};

var sayHello = function() {
    return 'Hello ' + this.name;
};

如果我将对象绑定到 sayHello (sayHello.bind(user)) 或如果我使用 user.sayHi(); 时,这两个函数将给出相同的结果;

所以我的问题是,是否有理由使用一种方法而不是另一种方法?我想我在某处读到不鼓励在原型上创建东西,如果是这样,为什么?

更正:

我错误地写了 Object.prototype.. 而不是指定 (Object I create).prototype..

【问题讨论】:

  • 这是不好的做法,专门修改Object.prototypeuser.sayHello = function(){}function sayHello(obj){} 怎么样?
  • 通过将sayHi 添加到Object.prototype,现在几乎所有东西都有sayHi 方法。
  • 你不应该接触 Object.prototype。否则,所有对象都继承此方法。 new Date().sayHi(), window.sayHi(), /\d/.sayHi()...
  • 您的“更正”完全改变了问题,但您将代码原样保留;我很困惑。
  • 这是否决票的原因吗?一个抬头然后有机会修改就可以了。不管怎样,我已经解决了。

标签: javascript prototype call bind apply


【解决方案1】:

修改 Object.prototype 是非常糟糕的做法,因为每个对象都继承自它,所以现在创建的每个对象都会有一个名为 sayHi 的方法,即使是没有属性名称的对象。

如果您要创建自己的类 say,可以将 sayHi 方法添加到原型列表中,因为这样只有该类型的实例才有该方法:

function Person(name){
   this.name = name;
}

Person.prototype.sayHi = function() { return 'Hi ' + this.name; }

至于选择一种或另一种方式,我会说主要是偏好。我倾向于对我创建的对象使用原型,并在内部范围内使用这些原型。

【讨论】:

    【解决方案2】:

    您不想使用Object.prototype.sayHi = function(){} 的原因是,一旦您这样做了,原型链中包含Object 的所有东西都可以使用sayHi。这就是原型继承的核心。

    可以将东西添加到创建的对象的原型中(添加到Object.prototype 被认为是不好的做法)。只要明白,当你这样做时,你的对象原型链中的任何东西都可以使用那个函数。

    function sayHello() {
        console.log("hello");
    }
    
    // Bad
    Object.prototype.hello = sayHello;
    Date.hello(); // Prints hello
    

    Call、Apply 和 Bind 实际上与添加到原型略有不同,Bind 也与 Call 和 Apply 不同。

    致电申请

    Function.call()Function.apply() 使用您在调用或应用时调用或应用的任何函数。

    例如,如果我们想在 NodeList 上使用 forEach() 方法

    var els = document.querySelectorAll("div");
    Array.prototype.forEach.call(els, function(el){
        el.classList.add("someClass");
    

    call 和 apply 的最大区别在于 call 采用可变参数,apply 采用 Array。

    function say() {
        console.log(arguments);
    }
    say.call(this, "a", "b");
    say.apply(this, ["a", "b"]);
    

    绑定

    不过,使用Function.bind() 实际上是另一回事。 Bind 允许您创建上下文绑定,您可以在需要时从特定上下文调用函数。

    function honk() {
        console.log(this.sound);
    }
    
    function Car() {
        this.sound = "honk";
    }
    
    function Van(){
        this.sound = "beep";
    }
    var c = new Car();
    var v = new Van();
    
    var ftorCar = honk.bind(c);
    var ftorVan = honk.bind(v);
    
    ftorCar(); // prints honk
    ftorVan(); // prints beep
    

    您现在可以传递ftorCar 并在需要时调用它,它将具有正确的“绑定”范围。

    【讨论】:

      猜你喜欢
      • 2011-07-05
      • 2020-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-22
      • 2015-09-13
      • 1970-01-01
      相关资源
      最近更新 更多