Introduction
1. Reference type
Reference type is an internal type in JavaScript. It is mainly used as a reference, replacing a variable or function. Of course, when the real value is needed, the real value can be found through it.
2. Structure of reference type
The value of a reference type consists of two parts. One is the object to which the object referred to by the value of the reference type belongs. Here we call it base, and the other is the object name of the object referred to in base. Represented in pseudo code:
Copy the code code as follows:
var valueOfReferenceType = {
base: <base object>,
propertyName: <property name>
};
3.Usage scenarios
There are two usage scenarios for reference types:
(1) When processing an identifier
Identifiers are variable names, function names, function parameter names, and unrecognized property names in global objects.
(2) When processing a property accessor
Copy the code code as follows:
var foo = 10;
function bar( ){}
In the intermediate results of the operation, the reference type corresponds to
Copy the code code as follows:
var fooReference = {
base: global,
propertyName: 'foo'
};
var barReference = {
base: global,
propertyName: 'bar'
};
It is still necessary to explain the base here. In JavaScript, all objects or functions have their own objects. Anyone who has read my previous article knows that there is a variable object in each execution context to manage the variables or functions in this execution context. .
So, when dealing with identifiers:
In the global context, it goes without saying that base === globalVO === gloabal
In the function's execution context, base === VO/AO
But the processing object properties are:
This is even simpler, base === owerObject
4. Get the true value of the reference type
As we said at the beginning, a reference type is just a reference, but it does not store the real value. When the real value is needed, it can be obtained through a series of internal algorithms. We can describe this algorithm with simple pseudocode:
Copy the code code as follows:
function GetValue(value) {
if (Type(value) != Reference) {
return value;
}
var base = GetBase(value);
if (base === null) {
throw new ReferenceError;
}
return base.[[Get]](GetPropertyName(value));
}
The internal [[Get]] method returns the true value of the object's properties, including analysis of inherited properties in the prototype chain. So through GetValue we can also easily obtain the real value of the reference type. For example:
Copy the code code as follows:
GetValue(fooReference); // 10
GetValue(barReference); // function object "bar"
So when do we need to get the real value of the reference type?
Generally, when a reference type needs to be assigned, participate in an operation, or is called, the real value needs to be obtained through the GetValue method. (Note: The object obtained through GetValue is no longer a reference type)
The relationship between reference types and this
The reference type is mainly closely related to the this point in the function context, and it looks quite different at different times, so we introduce the reference type to specifically explain the performance of this in the function context.
The general rules for determining the value of this in function context are as follows:
In the context of a function, this is provided by the caller and is determined by how the function is called. If the left side of the calling bracket () is a value of reference type, this will be set to the base object of the reference type value. In other cases (any other properties different from the reference type), this value will be null. However, there is no actual situation where the value of this is null, because when the value of this is null, its value will be implicitly converted to a global object. Note: In the fifth edition of ECMAScript, conversion to global variables is no longer forced, but is assigned to undefined.
Below we will discuss three situations based on the difference on the left side of the calling bracket:
(1) The left side of the calling bracket is the value of the reference type
This does not require too much analysis. The base object is the value of this. Just find the base. If it is declared under a global variable, it points to the global object.
Copy the code code as follows:
var myObject = {
foo : function(){
console.log(this);
}
}
myObject.foo(); //There is no doubt that the base of foo is myObject, so this in the foo method points to myObject.
(2) The left side of the calling bracket is a reference type value, but this value is null
Copy the code code as follows:
function myFunction() {
var foo = function(){
console.log(this);
}
foo(); //AO.foo() => null.foo()
}
myFunction(); //Output: Window {top: Window, window: Window...}
When an internal function is called, the base of the internal function should be the active object (OA) in the current execution context. However, within JavaScript, when OA is used as the base, it is treated as null. JavaScript certainly does not allow this to be null. , all the base is set to the global object (this is the source of the design error in the previous this function calling pattern). So in this case, this points to the global object.
(3) Call the value on the left side of the bracket that is not a reference type
Copy the code code as follows:
//Simple example
(function () {
console.log(this); // null => global
})();
//A more complex example
var foo = {
bar: function () {
console.log(this);
}
};
foo.bar(); // Reference, OK => foo
(foo.bar)(); // Reference, OK => foo
(foo.bar = foo.bar)(); // global
(false || foo.bar)(); // global
(foo.bar, foo.bar)(); // global
When the left side of the calling bracket is not a reference type but another type, this is automatically set to null and the result is the global object.
In the first example, the immediate function has an expression on the left side of the function call parenthesis, not a reference.
The second example is much more complicated, let’s analyze it one by one:
foo.bar(), there is no doubt about this, base is foo, and this points to foo.
(foo.bar)(), a parenthesis is used here, which acts as a grouping symbol, that is, it does not force the reference type to execute the GetValue method, and the execution result is exactly the same as above.
The next three, inside parentheses, are assignment operations, or operations and comma operations. They all force the reference type to execute the GetValue method, thereby returning a function object. In this way, the left side of the parentheses of the function call is no longer a reference type, so this points to the global object.
Summarize
Regarding reference types, I actually don’t know much about this. I just saw the chapter of this in Uncle Tom’s blog. In order to explain the value principle of this in the function call mode, I made a special analysis. This analysis is incredible. I I have always thought that there should be some relationship between reference types and reference-by-value. Unexpectedly, it is only used in bolg to assist in understanding this. As for whether there was a relationship between the two before, and if there was a relationship, what kind of relationship it was, I still need to continue to study and research.
I hope you can communicate more. I would like to thank Uncle Tom for this.