The big thing with bind is to remember that it changes the value of this
before you call the function. Meaning call
and apply
invoke the function immediately where as with bind
it allows us to change the value of this
and call the function like we normal would. This is super value especially when you don't want to call a function right away. A great example would be using bind during an event
where we do necessarily know when the user is going to fire the event, but we really care about the context of the function. ( we have an example for this)
so for some small examples. Consider the following...
function logThis(){
console.log(this.someObjectAttribute)
}
var object = { someObjectAttribute: 'Carne Asada'}
If I were to call this in the window we're going to see that .someObjectAttribute
is not an attribute for the window. If we were to do this in our browser the current context for this
is not the object we want to be talking about. If we remember rule 1
there is nothing we're doing to change or tell the javascript compiler
to know that this needs to be the object
.
So how do we chnage that?
we can essentially bind that function to the specific object we're talking about.
var boundObject = logThis.bind(object)
boundLogFoo() // 'Carne Asada'
Big thing to remember here is that you have to call the function because it isn't invoked immediately. Some of you might think that this isn't the most intuitive way to do this but it becomes really powerful when things get squirrelly when you're dealing with event listeners.
Let's say we're moving a block down and we want to change the x value.
function moveDown(offset){
return this.x + offset
}
Now if we run this code by passing an offset without defining this
we'll get a NaN
.
in our context here this
is the window. But if use call to define this
as an object we can change that offset.
var block = {x:0, y:2}
moveDown.call(block, 2) // the function will return the x of the block. In our case that will now be 4
function addThreeNumbers(first, second, third) {
return first + second + third;
}
var numbers = [1, 2, 3];
addThreeNumbers.apply(null, numbers);
Math.min(1, 4, 10, 2); // returns 1
Math.min(2, 3, 10, 100, 2048, 1984, 2012, 919); // returns 2
If we wanted to pass in an array we could do this...
var numbers = [201, 100, 2];
Math.min(numbers[0], numbers[1], numbers[2])
but that's super fragile.
it depends on us knowing how long the array is and we have to pass in our specific index.
apply()
lets us spread out the arguments.
var numbers = [2, 3, 10, 100, 2048, 1984, 2012, 919];
Math.min.apply(null, numbers); // returns 2;