In the following code:
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;
};
Both functions will give me the same result if I bind the object to sayHello (sayHello.bind(user)) or if I use user.sayHi();
So my question is, is there a reason to use one method over the other? I thought I've read somewhere that creating things on prototype is discouraged, if so why?
CORRECTION:
I erroneously wrote Object.prototype.. instead of specifying (Object I create).prototype..
The reason you don't want to use Object.prototype.sayHi = function(){}
is that once you do, everything that has Object
in its prototype chain will be able to use sayHi
. That's the core of prototypical inheritance.
It's OK to add things to the prototype of objects that you create (and it's just considered bad practice to add to Object.prototype
). Just understand that when you do, anything in your objects prototype chain will be able to use that function.
function sayHello() {
console.log("hello");
}
// Bad
Object.prototype.hello = sayHello;
Date.hello(); // Prints hello
Call, Apply, and Bind are actually slightly different from adding to prototype and Bind is also different from Call and Apply as well.
Function.call()
and Function.apply()
use whatever function you are calling or applying at the moment of the call or apply.
For example, if we wanted to use the forEach()
method on a NodeList
var els = document.querySelectorAll("div");
Array.prototype.forEach.call(els, function(el){
el.classList.add("someClass");
The big difference between call and apply is that call
takes a variadic argument and apply
takes an Array.
function say() {
console.log(arguments);
}
say.call(this, "a", "b");
say.apply(this, ["a", "b"]);
Using Function.bind()
is actually a different thing though. Bind lets you create a context binding where you can call a function from a specific context when you want.
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
You can now pass ftorCar
around and call it when you want to and it will have the correct scope "binding".