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”