[英]Call/Bind/Apply vs prototype
在下面的代码中:
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 ..而不是指定(我创建的对象).prototype ..
您不想使用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 and 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
采用数组。
function say() {
console.log(arguments);
}
say.call(this, "a", "b");
say.apply(this, ["a", "b"]);
使用Function.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
并在需要时调用它,它将具有正确的作用域“绑定”。
修改Object.prototype是非常不好的做法,因为每个对象都继承自它,因此,现在创建的每个对象都将具有一个名为sayHi的方法,即使没有属性名称的对象也是如此。
如果要创建自己的类say,可以将sayHi方法添加到原型列表中,因为这样只有该类型的实例才具有该方法:
function Person(name){
this.name = name;
}
Person.prototype.sayHi = function() { return 'Hi ' + this.name; }
至于选择一种或另一种方式,我会说这是首选。 我倾向于将原型用于我创建的对象,并在内部范围内使用这些原型运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.