In function calls, what is this and its decision? In ecma262, this is a relatively winding thing, and its description is scattered all over the world.
First, The caller provides the this value in 10.2.3. if the this value provided by the caller is not an object (note that null is not an object), then the this value is the global object. we can know that caller can provide us with this. If not, this is a global object. The problem arises again. How does caller provide this?
In 11.2.3, find The following description about Function CILS: The production CallExpression: MemberExpression Arguments is evaluated as follows:
1. Evaluate MemberExpression.
2. Evaluate Arguments, producing an internal list of argument values (see 11.2.4 ).
3. Call GetValue (Result (1 )).
4. If Type (Result (3) is not Object, throw a TypeError exception.
5. If Result (3) does not implement the internal [[Call] method, throw a TypeError exception.
6. If Type (Result (1) is Reference, Result (6) is GetBase (Result (1). Otherwise, Result (6) is null.
7. If Result (6) is an activation object, Result (7) is null. Otherwise, Result (7) is the same as Result (6 ).
8. Call the [[Call] method on Result (3), providing Result (7) as the this value and providing the list Result (2) as the argument values.
9. Return Result (8 ).
It can be seen from steps 6 and 7 that if the MemberExpression result is a Reference, this should be GetBase (Reference); otherwise, it is null. In step 7, the result of step 6 is the activity object, which is ignored here. I have another question. Reference? What is Reference and what is GetBase?
We found the Reference answer in 8.7. The description here is long. I just picked A section that meets our needs: a Reference is a reference to A property of an object. A Reference consists of two components, the base object and the property name.
The following abstract operations are used in this specification to access the components of references:
GetBase (V). Returns the base object component of the reference V.
GetPropertyName (V). Returns the property name component of the reference V.
Obviously, a Reference must Reference an attribute of an object. So we use obj. when method () is called, obj. the method Expression generates an intermediate Reference. The base object of this Reference is obj, so the result of GetBase is obj, so obj is provided by caller as this
I have seen many articles, taking calls like obj. method () as an example, and I think obj is a caller to explain these words:
The caller provides the this value. If the this value provided by the caller is not an object (note that null is not an object), then the this value is the global object.
This is actually impossible.
Caller cannot be obj. Otherwise, it will be interpreted by the attachEvent function or object method. Therefore, through the functions called by our own code, caller is determined by the execution control of the script engine; in the browser host environment triggered by an event, caller is determined by the behavior controlled by the browser.
------------------- Cutting line: stick to it, it's hard to write something positive, it's faster ----------------------
9. supplement the prototype chain-will the prototype chain be a circular chain?
This question was raised by telei. The answer is: no
Looking back at the [[Construct] Step, we can find that when an object obj is created, the obj. [[prototype] member is assigned to the prototype member of its constructor. However, when the prototype member of the constructor is referenced as another object, obj. [[prototype] is still the prototype object before the constructor.
The description code is as follows)
Function (){
This. testA = new Function ();
}
Function B (){
This. testB = new Function ();
}
Var a = new ();
B. prototype =;
// A. [[prototype] =={}; (not true, {} indicates the initial prototype object of Function. Same below)
Var B = new B ();
// B. [[prototype] =;
// B. [[prototype]. [[prototype] = a. [[prototype] = {};
A. prototype = B;
Var a2 = new ();
// A2. [[prototype] = B;
// A2. [[prototype]. [[prototype] = B. [[prototype] =;
// A2. [[prototype]. [[prototype]. [[prototype] = B. [[prototype]. [[prototype] =. [[prototype] == {};
// Finally, test it. It's funny.
Alert (a instanceof );
The last special explanation is: Well, the last funny thing in the code above is that it complies with the language implementation, but it is not in line with the logic of normal and abnormal people on earth. We know that object a is created by constructor A, so object a is an instance of object. However, as mentioned in the previous type determination, instanceof is determined by comparing prototype members of the constructor with the object prototype chain. So after object a is created, if the prototype of the constructor that creates it changes, a has nothing to do with its mother (constructor. Are you sure you want to change the prototype of the constructor to another object after instantiating the object?