Although I have been using these three things for a long time, I am quite comfortable with them. I know how to use them and the differences between them. However, I always feel that there is something missing when I am trying to conquer the highland of design pattern. And summed up some personal experience, to share with you.

this

Unlike in other languages, JavaScript’s this always refers to an object, and that object is dynamically bound based on the context in which the function is executed, not where the function is declared, but where the function is referenced.

This points to the

The articles on “baidu search, but there are problems, either summary is not complete, either talking about his own understanding, a purpose can write paragraphs shall not apply to the summary, have no choice but over the wall Google it, find a good article, article links go to the article in the resources section at the end.

Personal feeling Google search out of the value of learning materials higher, domestic search engine manufacturers estimate that the energy used in how to earn users’ money.

We know that this refers to an object, so it is relatively rich in meaning. It can be a global object, a current object, or any object, depending on how the function is called. There are several ways to call functions in JavaScript.

  • Called as a normal function (global object)
  • Method invocation as object (current object)
  • Call as constructor (arbitrary object)
  • Function.prototype.apply or function.prototype. call (any object)

1. Method calls as objects

window.name = 'globalName'; var myObj = { name: 'localName', getName: function(){ return this.name; }}; myObj.getName(); // localNameCopy the code

2. Called as a normal function

window.name = 'globalName'; 
var getName = function(){
	return this.name;
}; 
 
getName(); // globalName 
Copy the code

We assign the method call of an object to a variable, and when we convert it to a normal method, we get the following result

window.name = 'globalName'; var myObj = { name: 'localName', getName: function(){ return this.name; }}; var getName = myObj.getName; getName(); // globalNameCopy the code

We’ve all seen cases where a local callback refers to the window when a dom node is being used as a different function. In real development, we want it to refer to the window, and we often do.

html

<div id="div">this is a div</div>
Copy the code

js

window.id = 'window'; document.getElementById('div').onclick = function(){ var that = this; Var callback = function() {alert (that.id); // call callback callback(); };Copy the code

3. Called as a constructor

As we all know, JavaScript is an object-oriented language, but unlike other object-oriented programming languages, it doesn’t have a class concept. Instead, it has a prototype-based inheritance approach. JavaScript constructors are also very special, and if you don’t have the new keyword, it’s just like any other function, and in the course of development the constructor name starts with a capital letter, and some of you noticed it, some of you didn’t notice it, or you noticed it and you don’t know why, even if you write it in lower case, But that’s just amateurish, because the capitalized first letter here is for collaborative development, to standardize, and also to remind the caller to use the correct method so that this is bound to the newly created object.

Most JavaScript functions can be used as constructors. The constructor looks like a normal function except in the way it is called (new).

We should note that when the constructor is called by new, it returns this by default if it does not specify the object type, or the specified object type if it does. I’m sure anyone who’s ever written a plugin should have some idea of how to return an object of a given type.

var MyClass = function(){ this.name = 'lisi'; Return {name: 'LZB'}}; var obj = new MyClass(); obj.name; // lzbCopy the code

Note: The returned data type shown must be an object, other types are not used.

The apply/call call

I believe that those of you who are familiar with JavaScript know the sentence “everything is an object in JavaScript”. Therefore, functions are objects, and objects have methods, and apply and Call are the methods of function objects. These two methods are powerful and can be used to switch the execution context of functions, that is, the object that can change the this binding.

function MyObj() { this.name = 'lisi'; this.getName = function(){ return this.name; }}; var obj = new MyObj(); Var obj2 = {name: 'LZB '} var obj2 = {name:' LZB '} // lzbCopy the code

All roads lead to Rome

In fact, as a developer, I don’t like this summarization. It is not an Understanding of the principle, but a categorization of all usages involving this. The Understanding of JavaScript Function Invocation and “this” article is a little bit useful. The authors use apply/ Call as the basic method for function calls, and the other three methods have evolved from this, which is often referred to as syntactic sugar.

The function call process is the binding process of this. In all four cases, such a binding is completed. The difference is that when called as a normal function, this is bound to a global object. When called as a method on an object, this is bound to the object that the method belongs to.

Can’t find this

We’ve all seen implementations like this get element objects via document.getelementById (‘div’), but we don’t think it’s too cumbersome to use, so we’ll wrap it and replace it with a short function like this:

var getId = function(id) {
	return document.getElementById(id);
};

getId('div');
Copy the code

However, has anyone ever implemented this in the following way:

var getId = document.getElementById;

getId('div');
Copy the code

I’m sure some of you thought that way before you got to the first implementation, which is something you’ve used before, but then you used the first one, and it’s pretty clear that that’s not going to work, because we know that the internal implementation of the document.getelementById method is going to use this, In the second case getId is a normal function and its this refers to the window, so getELementById this refers to the window, but we know that getELementById is a method of the Document object, For normal use, the second method should point to document, while the second method points to window. Therefore, the second method has a problem, but we can fix it by using Apply and passing document as this to getId.

document.getElementById = (function(fn) {
	return function () {
		return fn.apply(document. arguments)
	}
})(document.getElementById);

var getId = document.getElementById;

getId('div');
Copy the code

This can be done by referring to the lang.hitch implementation in Dojo

button.onclick = lang.hitch(myObject, myObject.handler);
Copy the code

Call and apply

Call and Apply are widely used in functional programming style coding, as well as in JavaScript design patterns.

call vs apply

Apply takes two arguments. The first argument points to the this object in the function body, and the second argument is a collection with the following table (which can be an array or an array of classes). Apply passes the elements of the collection as arguments to the called function.

Call takes variable arguments. The first argument is the same as apply, and the remaining arguments are passed to the called function.

When a function is called, the JavaScript interpreter does not account for differences in the number, type, or order of its parameters and arguments. Instead, it uses an array to identify the js parameters (apply is more efficient than Call).

When we use call/apply, if the first argument is null, this in the function body points to the global object, but in strict mode null is returned.

You can enter the following code on the console:

Var func = function(a) {console.log(this === window)} func.apply(null) var func = function(a) {"use" strict"; console.log(this === null) } func.apply(null) // trueCopy the code

Call/apply purposes

We already know from the above example that their first use is to change the orientation of this inside a function

When we do interactive HTML work, we write JS that require separation of functionality and implementation.

var oDiv = document.getElementById('div');
oDiv.onClick = function() {
	func.apply(this)
};

function alertId() {
	alert(this.id)
}
Copy the code

Function.prototype.bind()

This method has been implemented since most advanced browsers. It is used to specify the “this” point inside a function. This method is compatible, but once we know what call/apply does, we can write our own method as follows:

Function.prototype.bind = function (context) { var that = this; This return function() {return that. Apply (context, arguments); var obj = { name: 'lzb' }; var getName = function() { console.log(this.name) }.bind(obj); getName(); // lzbCopy the code

Here we can also pass other parameters as follows:

Function.prototype.bind = function() { var that = this; var context = [].shift.apply(arguments); var args = [].slice.apply(arguments); return function() { return that.apply( context, [].concat.apply( [].slice.apply( arguments ), args) ) } } var obj = { name: 'lzb' }; var setName = function(name) { this.name = name; }.bind(obj, 'xxx'); Var getName = function() {console.log(this.name)}.bind(obj); setName(); // default is XXX // setName('snalv'); getName(); // sanlvCopy the code

There are many more complicated things you can do with BIND that I won’t cover here.

The resources

Understanding the “this” keyword in JavaScript

Let’s start with this in JavaScript

Understanding JavaScript Function Invocation and “this”