A directory

What’s the difference between a free front end and a salted fish

directory
A directory
Two var/let/const
Temporary dead zone
Four-function scope and block-level scope
Five variable promotion and function promotion
 5.1 Detailed explanation: variable promotion, function promotion and temporary dead zone
 5.2 title 1
 5.3 title 2
 5.4 title 3
 5.5 title 4
 5.6 the topic 5
Vi Judgment Variables
 6.1 typeof
 6.2 instanceof
 6.3 the constructor
 6.4 Array. Prototype. ToString. Call
Vii References

Two var/let/const

Returns the directory

  • var:
  1. varYou can repeat the declaration
  2. Scope: global scope and function scope
  3. Preparsing is done
  • let:
  1. You cannot duplicate declarations in a unified scope
  2. Scope: global scope and block-level scope{}
  3. No pre-parsing is performed
  • letvarComparison:
  1. varVariables can only be declared globally or as a whole function block
  2. letAllows you to declare a variable, statement, or expression that is scoped at the block level (block level scope)
  3. letCannot duplicate declaration
  4. letThere are temporal dead zones.
  5. Let ‘will not be preresolved (as of July 1)
  • const:
  1. letIt has some
  2. Initialization must be assigned
  3. The type cannot be changed after assignment

Temporary dead zone

Returns the directory

As long as the let/const command exists in the block-level scope, the variables declared by it are bound to the scope without external influence.

Inside a code block, a variable is not available until it is declared with let/const, hence the “temporary dead zone”.

Look at a question:

What does the following code output?

let a = 1;
let test = function() {
  console.log(a);
  a++;
}
test();
Copy the code

What does the following code output?

let a = 1;
let test = function() {
  console.log(a);
  let a = 2;
  a++;
}
test();
Copy the code

Output of the first problem: 1

Uncaught ReferenceError: Cannot access ‘a’ before initialization

The reason for this is that in the same block, let is redefined later, so the variable cannot be referenced before. At the same time, you cannot take values from nested outer layers.

Four-function scope and block-level scope

Returns the directory

  • Function scope: Defines a function in JavaScript whose internal variables can only be accessed from within the function, and which can modify and affect external variables.
  • Block-level scope: Variables are reclaimed immediately after they leave the defined block-level code, with the property of temporary dead zones.

In ES5, there are only global and function scopes, not block-level scopes, which can cause some trouble:

  1. Inner variables override outer variables
  2. The variable leakage of the loop is a global variable

Inner variables override outer variables

var tmp = new Date(a);function f(){
  console.log(tmp);
  if(false) {var tmp = "hello";
  }
}

f(); // undefined
Copy the code

The variable leakage of the loop is a global variable

for (var i = 0; i < 3; i++) {

}
console.log(i); / / 3
Copy the code

Variables declared through var or function declarations created in non-strict mode have no block-level scope.

var x = 1;
{
  var x = 2;
}
console.log(x); / / 2
Copy the code

So, to solve this problem, ES6 added block-level scopes:

  • A block statement is used to combine zero or more statements. The block consists of a pair of braces{}Define.

ES5 method of forming block-level scopes

(function() {

})()
Copy the code

ES6 is defined by {}

{
  var x = 1; // const x = 1;
}
Copy the code

Five variable promotion and function promotion

Returns the directory

There is no clear answer as to why variable promotion and function promotion are carried out.

Function promotion is to solve the problem of mutual recursion, can solve the bottom-up order problem in general.

// Verify even numbers
function isEven(n) {
  if (n === 0) {
    return true;
  }
  return isOdd(n - 1);
}

console.log(isEven(2)); // true

// Verify the odd number
function isOdd(n) {
  if (n === 0) {
    return false;
  }
  return isEven(n - 1);
}
Copy the code

If there is no function promotion, but a bottom-up order, isOdd is undeclared when isEven is called, so isOdd cannot be called inside isEven.

The reason for the increase in variables is not clear here.

5.1 Detailed explanation: variable promotion, function promotion and temporary dead zone

Returns the directory

So, what does variable promotion look like?

console.log(a);

var a = 10;
Copy the code

In this script, undefined is printed. Why?

var a;

console.log(10);

a = 10;
Copy the code

If you look at the code above, during JavaScript parsing, a will be extracted and declared above.

When console.log(a) is printed, it is undefined because A declared it but did not fill in the value.

What if this code were a let or const statement? There will be a temporary dead zone.

console.log(a);

let a = 10;
Copy the code

Output:

VM196:1 Uncaught ReferenceError: Cannot access 'a' before initialization
Copy the code

OK, a brief summary of variable promotion and temporary dead zones:

  • invarThe variable defined is printed before, because the variable is promoted, so it can be printedundefined
  • inlet,constDefinition of variables before printing, due to temporary dead zone problems, so an error.

Now look at function promotion:

var foo = 3;

function getFoo() {
  var foo = foo || 5;
  console.log(foo); / / output 5
}

getFoo();
Copy the code

Remember one sentence:

  • The function is a first-class citizen

So, in the above code, JavaScript parsing would become:

function getFoo() {
  var foo;
  foo = foo || 5;
  console.log(foo);
}

var foo;
foo = 3;

getFoo();
Copy the code

See, this is function promotion.

5.2 title 1

Returns the directory

function getFoo() {
  foo();

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

  foo();

  function foo() {
    console.log(2);
  }

  foo();
}
getFoo();
Copy the code

What does the above code output?


2
1
1
Copy the code

If we change it into variables and functions, we can know the effect after the promotion:

function getFoo() {
  var foo;

  function foo() {
    console.log(2);
  }

  foo(); / / 2

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

  foo(); / / 1

  foo(); / / 1
}
getFoo();
Copy the code

5.3 title 2

Returns the directory

console.log(a);

var a = 10;
var a = 100;

console.log(a);

function a() {
  console.log('a');
}
function a() {
  console.log('aa');
}

a();
Copy the code

What does the above code output?


The answer:

[Function: a]
100
a is not a function
Copy the code

5.4 title 3

Returns the directory

var a = 1;
function b() {
  a = 10;
  return;
  function a() {}
}
b();
console.log(a);
Copy the code

What does the above code output?


Answer: 1.

5.5 title 4

Returns the directory

function foo() {
  function bar() {
    return 3;
  }
  return bar();
  function bar() {
    return 8; }}console.log(foo());
Copy the code

What does the above code output?


Answer: 8

5.6 the topic 5

Returns the directory

var foo = { n: 1 };

(function(foo) {
  console.log(foo.n);
  foo.n = 3;
  foo = { n: 2 };
  console.log(foo.n);
})(foo)

console.log(foo.n);
Copy the code

What does the above code output?

  • A: One, two, three
  • B: Undefined 2 1
  • C: error
  • D: 1, 2, 1

The answer:

var foo = { n: 1 };
(function(foo){            // The parameter foo refers to the same memory space as the argument foo, where n has a value of 1
    var foo;               // The priority is lower than the parameter, invalid.
    console.log(foo.n);    / / output 1
    foo.n = 3;             // The value of n in the memory space pointed to by the argument foo is changed to 3
    foo = { n: 2 };        // The parameter foo refers to the new memory space, where n has the value 2.
    console.log(foo.n);    // Outputs the value of n for the new memory space
})(foo);
console.log(foo.n);        // The argument foo refers to the same memory space, where n is 3.
Copy the code

Vi Judgment Variables

Returns the directory

JavaScript determines variables in the following ways:

  • typeof(variable)
  • variable instanceof Array
  • variable.constructor = Array
  • Object.prototype.toString.call(variable)

What are the differences between them?

6.1 typeof

Returns the directory

var num = 123;
var str = 'abcdef';
var bool = true;
var arr = [1.2.3.4];
var json = { name: 'jsliang'.age: 25 };
var func = function () { console.log('this is function'); }
var und = undefined;
var nul = null;
var date = new Date(a);var reg = / ^ [a zA - Z] {5, 20} $/;
var error = new Error(a);console.log(
  typeof num, // number
  typeof str, // string
  typeof bool, // boolean
  typeof arr, // object
  typeof json, // object
  typeof func, // function
  typeof und, // undefined
  typeof nul, // object
  typeof date, // object
  typeof reg, // object
  typeof error, // object
);
Copy the code

Typeof can be distinguished by:

  • number
  • string
  • boolean
  • undefined
  • function

When detecting other types, all return Object, which is not very stable.

Supplement:

typeof NaN; // number
typeof 10n; // bigint
typeof Symbol(a);// symbol
Copy the code
  • NaNReturn tonumber
  • 10nBigIntIs appended to the numbernsaidBigIntOr,BigInt(10)Same thing.
  • Symbol()isSymbol

6.2 instanceof

Returns the directory

Instanceof determines the direction of the prototype chain, and we can take a look at its implementation principle:

function instanceOf(a, b) {
  // Determine the basic type using typeof
  if (typeofa ! = ='object' || b === null) {
    return false;
  }

  // getPrototypeOf is a built-in method of Object
  // Get the parameters of the prototype object
  let proto = Object.getPrototypeOf(a);
  const prototype = b.prototype;

  // Search from the current __proto__
  while (proto) {
    
    // If null is found and not found, return false
    if (proto === null) {
      return false;
    }

    // If A.__proto__. XXX === b.prototype, return true
    if (proto === prototype) {
      return true;
    }

    // Further iterationproto = proto.__proto__; }}Copy the code

Instanceof is a prototype chain lookup process.

var num = 123;
var str = 'abcdef';
var bool = true;
var arr = [1.2.3.4];
var json = { name: 'jsliang'.age: 25 };
var func = function () { console.log('this is function'); }
var und = undefined;
var nul = null;
var date = new Date(a);var reg = / ^ [a zA - Z] {5, 20} $/;
var error = new Error(a);console.log(
  num instanceof Number.// false
  str instanceof String.// false
  bool instanceof Boolean.// false
  und instanceof Object.// false
  nul instanceof Object.// false
  arr instanceof Array.// true
  json instanceof Object.// true
  func instanceof Function.// true
  date instanceof Date.// true
  reg instanceof RegExp.// true
  error instanceof Error.// true
)
Copy the code

To be on the safe side, Instanceof can tell:

  • Array
  • Function
  • Date
  • RegExp
  • Error

I’m not sure about the rest.

6.3 the constructor

Returns the directory

var num = 123;
var str = 'abcdef';
var bool = true;
var arr = [1.2.3.4];
var json = { name: 'jsliang'.age: 25 };
var func = function () { console.log('this is function'); }
var und = undefined;
var nul = null;
var date = new Date(a);var reg = / ^ [a zA - Z] {5, 20} $/;
var error = new Error(a);function Person(){}var Tom = new Person();

console.log(
  Tom.constructor === Person,
  num.constructor === Number,
  str.constructor === String,
  bool.constructor === Boolean,
  arr.constructor === Array,
  json.constructor === Object,
  func.constructor === Function,
  date.constructor === Date,
  reg.constructor === RegExp,
  error.constructor === Error
);
Copy the code

All results are true; except for undefined and null, the other types can be judged by constructor.

However, because the constructor property can be modified, the results detected may be incorrect.

6.4 Array. Prototype. ToString. Call

Returns the directory

var num = 123;
var str = 'abcdef';
var bool = true;
var arr = [1.2.3.4];
var json = { name: 'jsliang'.age: 25 };
var func = function () { console.log('this is function'); }
var und = undefined;
var nul = null;
var date = new Date(a);var reg = / ^ [a zA - Z] {5, 20} $/;
var error = new Error(a);console.log(
  Object.prototype.toString.call(num), // [object Number]
  Object.prototype.toString.call(str), // [object String]
  Object.prototype.toString.call(bool), // [object Boolean]
  Object.prototype.toString.call(arr), // [object Array]
  Object.prototype.toString.call(json), // [object Object]
  Object.prototype.toString.call(func), // [object Function]
  Object.prototype.toString.call(und), // [object Undefined]
  Object.prototype.toString.call(nul), // [object Null]
  Object.prototype.toString.call(date), // [object Date]
  Object.prototype.toString.call(reg), // [object RegExp]
  Object.prototype.toString.call(error), // [object Error]
);
Copy the code

A perfect method to detect all the types mentioned above is to render result.slice(8, -1) to get the specific type.

Vii References

Returns the directory

  • JavaScript: Variable promotion and function promotion【 Reading Suggestions: 10min】
  • Issues that must be paid attention to in variable promotion【 Reading Suggestions: 5min】
  • Js front-end variable promotion problem【 Reading Suggestions: 5min】
  • Some holes in JS variable promotion【 Reading Suggestions: 5min】
  • JS to determine the type of a variable【 Reading Suggestions: 10min】
  • What is the difference between block-level scope and function scope in JS? (Code parsing)【 Reading Suggestions: 5min】

Jsliang’s document library is licensed by Junrong Liang under the Creative Commons Attribution – Non-commercial – Share alike 4.0 International License. Based on the github.com/LiangJunron… On the creation of works. Outside of this license agreement authorized access can be from creativecommons.org/licenses/by… Obtained.