Javascript talk about reference types

  • 2020-03-30 00:57:53
  • OfStack

Introduction to the
1. Reference type
A reference type is an internal type in javascript. It is mainly used as a reference, instead of a variable or function, and of course can be used to find the real value when the real value is needed.

2. Structure of reference type
When referring to a value of a type, it consists of two parts: one is the object to which the value of the reference type refers, which is called base, and the other is the name of the object in base. Pseudo-code is used to represent:


var valueOfReferenceType = {
base: <base object>,
propertyName: <property name>
};

3. Use situations
There are two usage scenarios for reference types:

(1) when dealing with an identifier

Identifiers are variable names, function names, function parameter names, and unknown attribute names in global objects.

(2) when working with a property accessor


var foo = 10;
function bar( ){}

In the intermediate result of the operation, the reference type corresponds


var fooReference = {
        base: global,
        propertyName: 'foo'
    };

    var barReference = {
        base: global,
        propertyName: 'bar'
    };

Again, it's worth explaining base, because in javascript all objects or functions have their own objects, and as anyone who has read my previous article knows, there's a variable object in each execution context that manages the variables or functions in that execution context.

So, when dealing with identifiers:

In the global context, there is no doubt that base === globalVO === gloabal

In the execution context of the function, base === VO/AO

But the processing object properties are:

This is even simpler, base === owerObject

Get the true value of the reference type
We said at the beginning that a reference type is just a reference, not that it doesn't hold the real value. When real values are needed, they can be obtained through an internal set of algorithms. This algorithm can be described by simple pseudo-code:


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 property, including the analysis of inherited properties in the prototype chain. All through GetValue we can also easily get the real value of the reference type. The following cases:


GetValue(fooReference); // 10
GetValue(barReference); // function object "bar"

So when do we need to get the real value of the reference type?

Typically, a reference type needs to be assigned, evaluated, or called to get the real value through the GetValue method. (note: the object retrieved through GetValue is no longer a reference type)

The relationship between the reference type and this
The reference type is mainly related to the this point in the function context, and it seems quite different from time to time, so we introduce the reference type to explain the performance of this in the function context.

The general rule for determining this value in the context of a function is as follows:

In a function context, this is provided by the caller, depending on how the function is called. If the left hand side of the call parenthesis () is the value of the reference type, this is set to be the base object for the value of the reference type, and in other cases (any other property that is different from the reference type), this value is null. However, there is no case where the value of this is null, because when the value of this is null, its value is implicitly converted to a global object. Note: in ECMAScript version 5, global variables are no longer forced to be converted, but are assigned to undefined.

We will discuss the following three cases according to the difference on the left side of the call parenthesis:

(1) the value of the reference type is on the left of the call parenthesis

You don't have to do a lot of analysis, the base object is this value, just find the base. If it is declared under a global variable, it points to the global object.


var myObject = {
     foo : function(){
            console.log(this);
      }  
}
myObject.foo(); //There is no doubt that the base of this foo is myObject, so this in the foo method points to myObject.

(2) the value of the reference type is on the left of the call parenthesis, but it is null


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 invoked, the internal function of the base should be the current execution context active objects (OA), but within the javascript in the OA as base, both as a null, javascript, of course, does not allow this is null, all will set the base for the global object (which is above this function invocation pattern design error source). So in this case, this all points to the global object.

(3) the value to the left of the call parenthesis is not of the reference type


//A simpler example
(function () {
  console.log(this); // null => global
})();
//A more complicated 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 call bracket is not a reference type but another type, this is automatically set to null and the result is a global object.

In the first example, the immediate function, whose function call bracket is left with an expression, not a reference.

The second example is much more complicated. Let's analyze one by one:

Foo.bar (), no doubt about that, base is foo, this points to foo.

(foo.bar)(), which USES a little bracket here, which ACTS as a grouping symbol here, meaning that it does not force the reference type to execute the GetValue method, which executes exactly as above.

The next three, in turn, are the assignment, or, and comma operations, which force the reference type to execute the GetValue method, thus returning a function object. So the left hand side of the function call is no longer the reference type, so all of this is pointing to the global object.

conclusion

On a reference type, actually I don't know all this, just see this in uncle Tom's blog that chapter, in order to explain the value of this principle and the function invocation pattern special analysis and the analysis must be enormous, until I think there should be some reference types and the reference values, unexpectedly, it uncle bolg is only used to assist in understanding this. As for whether there was a relationship between them before, if there was a relationship, what kind of relationship it was, I had to continue to study.


Related articles: