1. Examples of variable promotion

1.1 eg1

  • Form global execution Context EC(G)
  • Lexical analysis, prior to code execution
  • Variable promotion (in the current context with var and function declared in advance)
  • var a; var b; var c; Var is declared but not defined. The global context is based on var and function, and the corresponding properties are also set in window
  • fn = 0x000; Create heap memory to hold code strings
  • Code execution stage (things done in variable promotion stage are not repeated in code execution stage and will be ignored)
console.log(a, b, c);   // undefined undefined undefined
var a = 12,
    b = 13,
    c = 14.function fn(a) {    // fn has already declared + definition when promoting, code execution phase skips this phase
  /* Private context initialization scope chain: 
      
        Parameter assignment: a = 10 Variable promotion: no var and function code execution */
      (fn),>
  console.log(a, b, c);  // a private 10 b and c look for 13 14 in EC(G)
  a = 100;  // Private a = 100
  c = 200;  // global c = 200
  console.log(a, b, c);  / / 100 13, 200
  
  // The function returns no value after completion. Undefined is returned by default
  // The current context is not occupied outside the stack
}
b = fn(10);  // execute the function first, return the result to b b = undefined
console.log(a, b, c);  // 12 undefined 200
Copy the code

1.2 eg2

  • In the global context, variables are promoted
  • var i; A=0X000; [[scope]]:EC(G) scope is global
  • var y; B=0x001; [[scope]]:EC(G)
  • Code execution I = 0;
var i = 0;

function A() {
  /* EC(A1) scope chain 
      
        parameter assignment: var I; X = 0x100 [[scope]]:EC(A1) scope is A1 execute I = 10 */
      (a1),>
  var i = 10;
  function x() {
    console.log(i)
  }
  return x;  // return 0x100  
  
  // 0x100 is occupied by global y and cannot be released. Closure is reserved
}

var y = A();  // A() returns the result to y = 0x100
y();  / / 10

function B() {
  var i = 20;
  y();
}
B();  / / 10
Copy the code

When a function is executed, its parent scope (context) is not related to where the function is executed, but only where it is created. Where is the function created

1.3 eg3

  • Variable promotion:
    • var a;
    • var obj;
    • fn = 0x000; [[scope]]: EC(G) No matter where fn executes, fn’s parent context is always global
  • Code execution
var a = 1;
var obj = {   // 0bj = 0x001 Object open heap memory
  name: 'tom'
};

function fn() {
  /* fn executes a private context chain 
      
        parameter assignment: var a2; // Only a2 is private, a/obj2/obj are global code execution is not occupied, free */
      (fn),>
  var a2 = a;  // a2 = 1
  obj2 = obj;  // Add obj2 to winndow, obj2 = 0x001
  a2 = a;   // a2 = 1
  obj2.name = 'jack';  // 0x001.name = 'jack'
}
fn();  / / implementation of fn
console.log(a);  / / 1
console.log(obj);  // {name: 'jack'}
Copy the code

1.4 eg4

  • Variable ascension
    • var a;
    • fn = 0x000; [[scope]]:EC(G)
  • Code execution
var a = 1;    // a = 1
function fn(a) {
  /* EC(fn) initialize the scope chain 
      
        parameter a = 1 var a; (already corporeal parameter a, a variable already exists AO(Fn) this promotion will be ignored) a = 0x001; [[scope]]:EC(fn) does not redeclare a, but reassigns code to execute */
      (fn),>
  console.log(a)  // 0x001
  var a = 2;  // reassign
  console.log(a)  / / 2
  function a() {}   // Variable promotion has been handled, code execution skipped
  console.log(a)  / / 2
}
fn(a);  / / execution fn (1)
console.log(a)  // 1 global a
Copy the code

1.5 eg5

1.5.1 case 1
  • Variable promotion:
    • var a;
    • fn = 0x000; [[scope]]:EC(G)
  • Code execution
console.log(a);  // undefined
var a = 12;
function fn() {
  /* fn performs initialization of the scope chain 
      
        parameter assignment: var a; // Private a */
      (fn),>
  console.log(a);  // undefined
  var a = 13;   // Private a = 13
}
fn();  / / execution
console.log(a);  / / 12
Copy the code
1.5.2 case 2
  • Variable promotion:
    • var a;
    • fn = 0x000; [[scope]]:EC(G)
  • Code execution
console.log(a);  // undefined
var a = 12;
function fn() {
  /* fn performs initialization of the scope chain 
      
        parameter assignment: no variable promotion: no private variable */
      (fn),>
  console.log(a);  / / 12
  a = 13;   // global a = 13
}
fn();  / / execution
console.log(a);  / / 13
Copy the code
1.5.3 scenario 3
  • Variable promotion:
    • fn = 0x000; [[scope]]:EC(G)
  • Code execution
console.log(a);  // If the output variable is not its own private variable, find the superior
a = 12;
function fn() {
  console.log(a);  / / 12
  a = 13;   // global a = 13
}
fn();  / / execution
console.log(a);  / / 13
Copy the code

1.6 eg6

  • Variable promotion:
    • var foo;
    • Self-executing function, does not participate in variable promotion, code is created until run
var foo = 'hello';
(
  function (foo) {
    /* EC(any) initializes the scope chain 
      
        parameter assignment: foo = 'hello' Variable promotion: var foo, the current context has foo, ignores this step to declare code execution */
      (any),>
    console.log(foo);   // hello
    var foo = foo || 'world';  // foo = 'hello'
    console.log(foo);   // 'hello'
  }
)(foo);   // The self-executing function executes. Pass the argument 'hello'
console.log(foo);  // hello
Copy the code
  • && and | |
    • A | | B: A true return A value, A false returns the value of B,
    • A&&B: returns the value of B if A is true, and returns the value of A if A is false
    • && and | | appeared at the same time, && priority is higher than | |

1.7 eg7

// 
{
  function foo() {}
  foo = 1;
}
console.log(foo);


// ---------------

{
  function foo() {}
  foo = 1;
  function foo() {}}console.log(foo);


// ---------------

{
  function foo() {}
  foo = 1;
  function foo() {}
  foo = 2;
}
console.log(foo);
Copy the code

2. Data type

2.1 aobjectTo a value of the data typeNumber/string

  • Converts a value of an object data type to a number/string

    • First look up the object’sSymbol.toPrimitiveattribute
    • If it does not, the next call to the object’svalueOfMethod to get the original value (primitive type value)
    • If the original value cannot be obtained, call againtoStringTo a string orNumberConvert to numbers
  • scenario

    • in+If there are strings (or partial object values) on the left and right sides of an operation, it is not a mathematical operation, but a string concatenation
    • Alert will implicitly convert the value to a string output
    • String concatenation, template string to achieve string concatenation, encounter object will be converted into a string
    • In the rest of the math, for example- / * %Will convert the object to a number
    • = =In comparison, objects are also converted to strings or numbers
let obj = {
  name: 'this is a obj'
}
let arr = [10.20.30]
let time = new Date(a)let num = new Number(10)
console.log(obj, arr, time, num)
Copy the code


console.log(10 + obj)  // '10[object, Object]'
// 1. obj[Symbol.toPrimitive] => undefined
// 2. obj.valueof () => {name: 'XXX '} is not the original value, the original value is the basic type
// 3. obj.toString() => '[object, Object]'

console.log(10 + num)  / / 20
// 1. num[Symbol.toPrimitive] => undefined
// 2. obj.valueof () => 10 is the original value. The original value is the basic type


obj[Symbol.toPrimitive] = function() {
  return 100;
}
console.log(10 + obj)  / / 110


// The default argument hint
obj[Symbol.toPrimitive] = function(hint) {
  console.log(hint)  // => Default, number, or string
  return 100;
}

Copy the code