1.1.1 Summary I believe that everyone with programming experience in C, C# or Java is very familiar with the this keyword. Since Javascript is an object-oriented programming language, it contains the this keyword just like C, C# or Java. Next, we will introduce to you the this keyword in Javascript.
Directory of this article
this in global code
this in function
reference type
function call and non-reference type
reference type and null value of this
function as constructor The value of this when the function is called
Manually set the value of this when the function is called
1.1.2 Text Since many object-oriented programming languages include this Keyword, we will naturally associate this with object-oriented programming. This usually points to the object newly created using the constructor. In ECMAScript, this is not only used to represent the created object, but also an attribute of the execution context:
activeExecutionContext = {
// Variable object.
VO: {...},
this: thisValue
};
This in global code
// Global scope
// The implicit property of
// the global object
foo1 = "abc";
alert(foo1); // abc
// The explicit property of
// the global object
this.foo2 = "def";
alert(foo2); // def
// The implicit property of
// the global object
var foo3 = "ijk";
alert(foo3); // ijk
Earlier we defined the global properties foo1, foo2 and foo3 explicitly and implicitly. Since this is in the global context, so Its value is the global object itself (window object in browsers); we will introduce this in functions next.
This in the function
When this is in the function code, the situation is much more complicated and will cause many problems.
The first characteristic (and the most important characteristic) of this value in function code is that it is not statically bound to the function.
As mentioned before, the value of this is determined when entering the execution context (Excution context), and in function code, its value is different every time.
However, once the code is executed, its value cannot be changed. It is impossible to assign a new value to this, because this is not a variable at all at that time.
Next, we illustrate this in the function through specific examples.
First we define two objects foo and person. foo contains an attribute name, and person contains the attribute name and the method say(). The specific definition is as follows:
// Defines foo object.
var foo = {
name: "Foo"
};
// Defines person object.
var person = {
name: "JK_Rush",
say: function() {
alert(this === person);
alert( "My name is " this.name);
}
};
person.say(); // My name is JK_Rush
// foo and person object refer to
// the same function say
foo.say = person.say;
foo.say(); // My name is Foo.
Through the above code, we find that calling person When using the say() method, this points to the person object, and when the say() method of foo points to the say() method in peson through assignment. We call the say() method of foo and find that this does not point to the person object, but to the foo object. What is the reason for this?
First of all, we must know that the value of this is non-static in the function. Its value is determined when the function is called. Before the specific code is executed, the value of this is determined by the caller who activates the context code. For example, calling The outer context of the function; more importantly, the value of this is determined by the form of the calling expression, so this is not statically bound to the function.
Since this is not statically bound to the function, can we dynamically modify the value of this in the function?
// Defines foo object.
var foo = {
name: "Foo"
};
// Defines person object.
var person = {
name: "JK_Rush",
say: function() {
alert(this === person);
this = foo; // ReferenceError
alert("My name is " this.name);
}
};
person.say (); // My name is JK_Rush
Now we dynamically modify the value of this in the method say(). When we re-execute the above code, we find that the value of this is referenced incorrectly. This is because once the code execution phase is entered (when the function is called, before the specific code is executed), the value of this is determined and cannot be changed.
Reference type
We mentioned earlier that the value of this is determined by the caller who activates the context code. More importantly, the value of this is determined by the form of the calling expression; then the form of the expression is How to affect the value of this?
First, let us introduce an internal type - a reference type. Its value can be expressed in pseudo code as an object with two properties: the base property (the object to which the property belongs) and the propertyName in the base object. Attributes:
// Reference type.
var valueOfReferenceType = {
base: mybase,
propertyName : 'mybasepropertyName'
};
The value of reference type can only be in the following two situations:
When processing an identifier When used as
or when accessing attributes,
identifiers are actually variable names, function names, function parameter names, and unrestricted attributes of global objects.
// Declares varible.
var foo = 23 ;
// Declares a function
function say() {
// Your code.
}
In the intermediate process, the corresponding reference types are as follows:
// Reference type.
var fooReference = {
base: global,
propertyName: 'foo'
};
var sayReference = {
base: global,
propertyName: 'say'
};
We know that there are two ways to access properties in Javascript: dot notation and square bracket notation:
// Invokes the say method.
foo.say();
foo['say']();
Because say( ) method is an identifier, so it corresponds to the foo object reference type as follows:
// Reference type.
var fooSayReference = {
base: foo,
propertyName: 'say'
};
We found say() If the base attribute value of the method is the foo object, then its corresponding this attribute will also point to the foo object.
Suppose we call the say() method directly, and its corresponding reference type is as follows:
// Reference type.
var sayReference = {
base: global,
propertyName: 'say'
};
Due to The base attribute value of the say() method is global (usually the window object), then its corresponding this attribute will also point to global.
The value of this in the function context is provided by the function caller and is determined by the form of the current calling expression. If there is a reference type value on the left side of the calling bracket (), then the value of this will be set to the base object of the reference type value. In all other cases (non-reference types), the value of this is always null. However, since null has no meaning to this, it is implicitly converted to the global object.
Function calls and non-reference types
We mentioned earlier that when the left side of the call bracket is a non-reference type, the value of this will be set to null and eventually converted to a global object implicitly.
Now we define an anonymous self-executing function, the specific implementation is as follows:
//Declares anonymous function
(function () {
alert(this); // null => global
})();
Since the anonymous function on the left side of the bracket () is a non-reference type object (it is neither an identifier nor a property access), the value of this is set to the global object.
// Declares object.
var foo = {
bar: function () {
alert(this);
}
};
(foo. bar)(); // foo.
(foo.bar = foo.bar)(); // global?
(false || foo.bar)(); // global?
( foo.bar, foo.bar)(); // global
Notice here that among the four expressions, only the first expression this points to the foo object, while the other three expressions The formula executes global.
Now we have another question: Why does property access, but the final value of this is not a reference type object but a global object?
We noticed that expression two is an assignment operator. Different from the expression set of operators, it will trigger the call to the GetValue method (see the third step in 11.13.1). When finally returned, it will be a function object (rather than a reference type value), which means that the value of this will be set to null, and eventually it will become a global object.
The third and fourth cases are similar - the comma operator and OR logical expression will trigger the call to the GetValue method, so accordingly the original reference type value will be lost and become a function type, the value of this It becomes a global object.
Reference type and the null value of this
For the previously mentioned situation, there are exceptions. When the left side of the calling expression is the value of the reference type, but the value of this is null, it eventually becomes global. Object (global object). The condition for this to happen is when the base object of the reference type value happens to be an activation object.
This happens when an internal child function is called in a parent function. The active object is introduced by the following schematic code:
// Declares foo function.
function foo() {
function bar() {
alert(this); / / global
}
// The same as AO.bar().
bar();
}
Since the activation object will always The returned this value is - null (using pseudo code to represent AO.bar() is equivalent to null.bar()), and then the value of this will eventually be converted from null to a global object.
Exceptions occur when a function call is contained within a code block of a with statement, and the with object contains a function attribute. The with statement will add the object to the front of the scope chain, before the active object. Correspondingly, in the case of reference type values (identifiers or property access), the base object is no longer the active object, but the object of the with statement. In addition, it is worth mentioning that it is not only for internal functions, but also for global functions. The reason is that the with object masks higher-level objects in the scope chain (global objects or active objects):
Function as constructor The value of this when called
When the function is used as a constructor, when we create an instance object through the new operator, it will call the internal [[Construct]] method of the Foo() function; after the object is created, it will call the internal [[Call]] method, then the value of this in all Foo() functions will be set to the newly created object.
//Declares constructor
function Foo() {
// The new object.
alert(this);
this.x = 10;
}
var foo = new Foo();
foo.x = 23;
alert(foo.x); // 23 Manually set the value of this when the function is called
Function.prototype defines two methods on the prototype, allowing you to manually specify the value of this when the function is called. . These two methods are: .apply() and .call(). Both methods accept the first parameter as the value of this in the calling context, and the difference between the two methods is the parameters passed. For the .apply() method, the second parameter accepts an array type (or class Array of objects, such as arguments), while the .call() method accepts any number of arguments (separated by commas); only the first argument of these two methods is necessary - the value of this.
Introducing the use of call() method and apply() method through sample code:
var myObject = {};
var myFunction = function(param1, param2) {
//setviacall()'this'points to my Object when function is invoked
this. foo = param1;
this.bar = param2;
//logs Object{foo = 'foo', bar = 'bar'}
console.log(this);
};
// invokes function, set this value to myObject
myFunction.call(myObject, 'foo', 'bar');
// logs Object {foo = 'foo', bar = 'bar'}
console.log(myObject);
The first parameter of the call() method is the necessary this value. Then we can pass any number of parameters. Next, we will introduce the use of the apply() method.
var myObject = {};
var myFunction = function(param1, param2) {
//set via apply(), this points to my Object when function is invoked
this.foo=param1;
this.bar=param2;
// logs Object{foo='foo', bar='bar'}
console.log(this);
};
// invoke function, set this value
myFunction.apply(myObject, ['foo', 'bar']);
// logs Object {foo = 'foo', bar = 'bar'}
console.log(myObject);
By comparing with the call() method, we found that there is not much difference between the apply() method and the call() method, except that the method signatures are different.
1.1.3 Summary This article introduces the use of this in Javascript, and more importantly, helps us better understand the use of this value in globals, functions, and constructors and changes in the median value in some special cases.
The value of this in a function context is provided by the function caller and is determined by the form of the current calling expression. If there is a reference type value on the left side of the calling bracket (), then the value of this will be set to the base object of the reference type value. In all other cases (non-reference types), the value of this is always null. However, since null has no meaning to this, it is implicitly converted to the global object.
For special cases, we must remember that assignment operators, comma operators and || logical expressions will cause this to lose its original reference type value and become a function type, and the value of this will become a global object.
Reference
[1]
http://dmitrysoshnikov.com/ecmascript/chapter-3-this/ English version
[2]
http:// blog.goddyzhao.me/post/11218727474/this Translation
[3]
https://net.tutsplus.com/tutorials/javascript-ajax/fully-understanding-the-this-keyword/ [Author]: JK_Rush