This is the fourth day of my participation in the August More Text Challenge. For details, see “August More Text Challenge”.

preface

Talk about this in the execution context

In the context of JavaScript execution, there are:

Variable environment (which holds variables declared by var in the current execution context),

Lexical environments (variables that hold let, const declarations in the current execution context block),

Outer (refers to the upper execution context, determined by the nested relationship in the static code, and the global context has a value of NULL),

And a this?

It looks like this is not going to work throughout the entire execution of JavaScript. What is this for?

Conclusion: Using the this mechanism, we use the properties inside the object in the methods inside the object.

This is basically a standard, and browsers implement it according to the standard, so to understand this, you have to look at some classic examples, and the more examples you understand, the more inventory you’ll have. You can better understand the 1,2,3 that others have summarized from the ECMA specification.

Definition of this value (MDN) :

A property of the current execution context (global, function, or eval) that, in non-strict mode, always points to an object, and can be any value in strict mode.

A classic case

Case 1 (Entry level)

// This in the global environment points to the global object console.log(this)Copy the code

This is the definition, not to repeat

Case 2 (Minor White Level)

var obj = { foo: function () {console.log(this.bar)}, bar: 1 }; var foo = obj.foo; var bar = 2; Foo (); foo(); foo(); foo(); foo()Copy the code

Var obj = {… }

In essence, a heap memory address is assigned a value to obj, which refers to an object in the memory space.

Obj.foo () is an object call method

This refers to OBj

var foo = obj.foo

It essentially assigns a value to obj of a heap memory address, which refers to a function of memory space.

Foo () is equivalent to function execution in the global environment

This points to the global object

Reference: www.ruanyifeng.com/blog/2018/0…

Case 3 (Rookie level)

Var myObj = {name: "geek time ", showThis: Function (){console.log(this) function bar(){console.log(this)} bar()} myobj.showthis () // bar() this refers to the global object The classic reason for this case is that most of the bugs come from here // analysis (perhaps too much analysis) : functions that execute other functions are no different from functions that execute in the global environment. // You can use this from showThis in the bar function by using the arrow function and the closureCopy the code

Case 4 (Examination level)

1 func(p1, p2) // 1 func(p1, p2) // 1 func(p1, p2) P2) // Not applyCopy the code

Syntax sugar 1 is equivalent to func.call(undefined, p1, p2)

Function func(){console.log(this)} function func(){console.log(this)}Copy the code

Syntax Sugar 2 is equivalent to obj. Foo.call (obj,p1,p2)

Var foo = {foo: function(){console.log(this)}} foo()Copy the code

PS: There is no such concept as “this” in the arrow function. The “this” in the arrow function is treated as the “this” in the outer function

Reference: zhuanlan.zhihu.com/p/23804247

So far, this core case is about these. The new, the arrow function, and even the strict mode feel irrelevant to the main thread of this mechanic, so I won’t go into it here, and I’ll go into it when I get to it.

Comb this in ECMAScript

ECMAScript types are divided into language types and canonical types.

ECMAScript language types are available to developers directly using ECMAScript. This is Undefined, Null, Boolean, String, Number, and Object.

Canonical types are equivalent to Meta-values and are used to describe the ECMAScript language structure and ECMAScript language types with algorithms. Specification types include Reference, List, Completion, Property Descriptor, Property Identifier, circumlocution, and Environment Record.

PS: Where Reference is closely related to this

The Reference type is used to explain the behaviour of such operators as delete, typeof, and the assignment operators.

So the Reference type is used to explain actions such as delete, typeof, and assignment.

A Reference is a resolved name binding.

A Reference consists of three components, the base value, the referenced name and the Boolean valued strict reference flag.

The base value is either undefined, an Object, a Boolean, a String, a Number, or an environment record (10.2.1).

A base value of undefined indicates that the reference could not be resolved to a binding. The referenced name is a String.

Reference consists of base value, referenced name, and strict Reference

The object where the base value attribute resides

Referenced Name Name of the attribute

strict reference

var foo = 1; Var fooReference = {base: EnvironmentRecord, name: 'foo', strict: false}; var foo = { bar: function () { return this; }}; foo.bar(); Var BarReference = {base: foo, propertyName: 'bar', strict: false};Copy the code

GetBase Reference method, which returns the base value of the Reference

IsPropertyReference Reference method that returns true if the base value is an object

GetValue Returns the true value of the object property

How to determine this in a Function call (11.2.3 Function Calls)

1. Calculate the MemberExpression result and assign the value to ref

2. Check whether ref is a Reference type

  • 2.1 If ref is Reference and IsPropertyReference(ref) is true, then this is GetBase(ref)

  • If ref is Reference and base value is Environment Record, then this value is ImplicitThisValue(ref)

  • 2.3 If ref is not Reference, the value of this is undefined

    var value = 1;

    var foo = { value: 2, bar: function () { return this.value; }}

    // Example 1 console.log(foo.bar()); // Example 2 console.log((foo.bar)()); // Example 3 console.log((foo.bar = foo.bar)()); / / the console. 4. The log ((false | | foo bar) ()); // Example 5 console.log((foo.bar, foo.bar)());

MemberExpression

Foo bar () / / here MemberExpression is foo bar / / according to the specification 11.2.1 PropertyAccessors, foo bar returns a Reference type / / to enter 2.1 The value of this is GetBase(ref), that is, foo (foo.bar)() // Where MemberExpression is (foo.bar) // according to 11.1.6 The Grouping Operator Bar = foo.bar)() // Where MemberExpression is (foo.bar = foo.bar) / / according to the specification 11.13.1 Simple the Assignment (=) MemberExpression for GetValue (rref) / / returns a Reference type / / (false | | foo bar), (foo bar, Foo. Bar) as in this case returns a non-reference type // Enter 2.3 this is undefined and is implicitly converted to a global object in non-strict mode // Add foo(); // The value of this is undefined // the value of this is undefined in non-strict mode is implicitly converted to a global objectCopy the code

reference

Github.com/mqyqingfeng…

yanhaijing.com/es5/#null

PS: Just a taste of this. As you go deeper, you feel the sting of being stared into the abyss. It would be foolish to dive into ecMAScript-related specifications at this point. Leave it to your future self.