--let ES6 learning and const command

let command

Basic Usage

ES6 add, to declare variables, similar to the usage var, the declared variable, only letvalid commands within the block where

{
    let a = 10;
    var b = 1;
}

a // a is not defined
b // 1

Var let in and for comparison cycle

// var声明
var a = [];

for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10

The above code, the variable iis vardeclared valid globally, so that only a global variable i. In each cycle, the variable ivalue will change, is assigned to the array within the loop aof functionthe run time, you will read the same through a variable closure i, resulting in a final output of the final ivalue, i.e. 10.

If used let, only the variable declared valid at the block level scope, the final output is 6.

// let声明
var a = [];

for (let i = 0; i < 10; i++) {
    a[i] = function() {
        console.log(i);
    };
}
a[6](); // 6

The above code, the variable iis letdeclared, the current iis only valid in the current round of cycle, so every time cycle iare in fact a new variable, the final output is 6. You might ask, if the variable cycle of each round iare again declared that it knows how the value of the previous cycle to calculate the value of the current round of the cycle? This is because the internal JavaScript engine will remember the value of the previous cycle, the variable is initialized round iwhen it is calculated on the basis of a round-robin.

forThere is a special loop is a loop portion of the parent scope, and the inner loop is a separate sub-scope.

for (let i = 0; i < 3; i++) {
  let i = 'abc';
  console.log(i);
}
// abc
// abc
// abc

The above code is output three times abc, indicating that the function of internal variables iand the external variables iare separated.

There is no variable lift

varCommand will happen "variable lift" phenomenon, that can be used before variable declarations, value undefined.

letCommand to change the behavior of grammar, the variable it must be declared in the statement, otherwise an error

// var 的情况
console.log(foo); // 输出undefined
var foo = 2;

// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;

Temporary dead zone

As long as there is scope block-level letcommands, variables declared it would "bind" in the region, free from external influence.

var tmp = 123;

if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}

ES6 clear that, if the block exists letand constcommand, this block these commands variable declarations, from the outset to form a closed scope. Those who would use these variables in a statement before the error is reported.

In short, in the code blocks letbefore the command to declare variables, the variables are not available. This is grammatically called "temporary dead zone"

"Temporary dead zone" also means that typeofno longer is a hundred percent safe operation.

typeof x; // ReferenceError
let x;

// 如果变量没有被声明
typeof undeclared_variable // "undefined"

Covert "dead zone"

function bar(x = y, y = 2) {
  return [x, y];
}

bar(); // 报错

// 解析:参数x等于参数y,但是此时参数y还没有被声明,如果是function bar(x = 2, y = x){}则不会报错,因为x已经声明,可以正常调用


// 不报错
var x = x;

// 报错
let x = x;
// ReferenceError: x is not defined

// 解析: let方式报错的原因同样是在变量x声明还没有执行完之前,取x的值

ES6 temporary provisions and the dead let, constthe statement does not appear to enhance variable, primarily to reduce run-time error that prevents you use the variable before the variable declaration, leading to unexpected behavior.

Not allowed to repeat a statement

letDo not allow the same scope, the statement repeated the same variable.

// 报错
function () {
  let a = 10;
  var a = 1;
}

// 报错
function () {
  let a = 10;
  let a = 1;
}

function func(arg) {
  let arg; // 报错
}

function func(arg) {
  {
    let arg; // 不报错
  }
}

Block-level scope

Why block-level scope?

ES5 only global scope and function scope, not block-level scope, which bring a lot of irrational scenes.

The first scenario, the inner layer may cover the outer variable variable.

var tmp = new Date();

function f() {
  console.log(tmp);
  if (false) {
    var tmp = 'hello world';
  }
}

f(); // undefined

Second scenario, the loop variable for counting the global variable leakage.

var s = 'hello';

for (var i = 0; i < s.length; i++) {
  console.log(s[i]);
}

console.log(i); // 5

The block-level scope ES6

letJavaScript actually added block-level scope.

ES6 allows any nested block-level scope.

Appears block-level scope, and actually makes the immediate implementation of a function expression (IIFE) is widely available is no longer necessary.

// IIFE 写法
(function () {
  var tmp = ...;
  ...
}());

// 块级作用域写法
{
  let tmp = ...;
  ...
}

Block-level scope and function declarations

ES5 provides that function only in the top-level scope and function scope statement, not a statement of scope at the block level.

ES6 introduction of block-level scope, declare the function explicitly allowed in the block-level scope. ES6 provisions, in block-level scope, the behavior is similar to the function declaration statement letcan not be referenced outside the block-level scope.

function f() { console.log('I am outside!'); }

(function () {
  if (false) {
    // 重复声明一次函数f
    function f() { console.log('I am inside!'); }
  }

  f();
}());

The above code runs in ES5, we get "I am inside!", Because ifthe function of the declaration fwill be raised to the head of the function, the following code is actually running.

// ES5 环境
function f() { console.log('I am outside!'); }

(function () {
  function f() { console.log('I am inside!'); }
  if (false) {
  }
  f();
}());

ES6 theoretically get "I am outside!". Because the function declared within a block-level role is similar let, there is no impact on the outside of the scope.

However, if you really run the above code in ES6 browser, it is being given, and

It turned out that if you change the block-level scope statement processing rules function, obviously have a significant impact on the old codes. To mitigate thus creating incompatibilities, ES6 in Appendix B, which provides that the browser can not achieve compliance with the above, have their own way of behavior .

  • It allows block-level domain acting function declaration.

  • Function declaration is similar var, that will increase to head global scope or function scope.

  • Meanwhile, the function declaration will be promoted to head of block-level scope is located.

Note that the above three rules only browser for ES6 effective to achieve other environments do not comply, or declare a function block-level scope as lettreatment.

According to these three rules, ES6 environment in the browser, a function declared within a block-level role, behavior similar to varvariable declarations.

// 浏览器的 ES6 环境
function f() { console.log('I am outside!'); }

(function () {
  if (false) {
    // 重复声明一次函数f
    function f() { console.log('I am inside!'); }
  }

  f();
}());
// Uncaught TypeError: f is not a function

In line with the above code ES6 browser, will be error, because the actual running the following code.

// 浏览器的 ES6 环境
function f() { console.log('I am outside!'); }
(function () {
  var f = undefined;
  if (false) {
    function f() { console.log('I am inside!'); }
  }

  f();
}());
// Uncaught TypeError: f is not a function

Taking into account the behavior of the environment caused by too different, and should be avoided at the block level scope function declaration. If you really need, it should also be written as a function of expression, rather than the function declaration statement.

// 函数声明语句
{
  let a = 'secret';
  function f() {
    return a;
  }
}

// 函数表达式
{
  let a = 'secret';
  let f = function () {
    return a;
  };
}

ES6 block-level scoping rules allow declaration of a function, was established only in the case of the use of braces, braces if no error is reported.

do expression (to understand)

Is a block-level scope statement, the operation of the plurality of packages together, there is no return value.

Now there is a proposal that can become an expression block-level scope, that can return value, way is to add before the block-level scope doso that it becomes doan expression.

let x = do {
  let t = f();
  t * t + 1;
};

const command

Basic Usage

constDeclare a read-only constant. Once the value of the statement, constants can not be changed, which means that constonce you declare a variable, you must initialize the immediate future can not be left to the assignment, the assignment is not just a statement, it will error.

constScope and letcommand the same: block-level role only in the region where it is declared effective.

constConstant command statement is not the upgrade, there are also temporary dead zone, can only be used in the back position statement.

Nature

constIn fact guaranteed, not the value of the variable may not change, but the memory address of the variable points shall not be altered. For simple data type (numeric, string, Boolean), that value is stored in the memory address pointed to by the variable, and therefore equal to the constant.

For complex data types (primarily objects and arrays), a variable memory address pointed to save only a pointer, constcan ensure that this pointer is fixed, as it points to the data structure is not variable, can not be controlled completely the

const foo = {};

// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop // 123

// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only

In the above code, the constant foostored in an address that points to an object. Immutable only this address, that is not the foopoint to another address, but the object itself is variable, it is still possible to add new attributes.

The object is frozen, you should use Object.freezethe method.

const foo = Object.freeze({});

// 常规模式时,下面一行不起作用;
// 严格模式时,该行会报错
foo.prop = 123;

The above code, the constant foopointing to an object frozen, so add a new property does not work, but also being given strict mode.

In addition to freezing the object itself, the object's properties should be frozen. The following is a function of the object completely frozen.

var constantize = (obj) => {
  Object.freeze(obj);
  Object.keys(obj).forEach( (key, i) => {
    if ( typeof obj[key] === 'object' ) {
      constantize( obj[key] );
    }
  });
};

Six Ways to declare variables ES6

var

function

let

const

import

class

Top-level object of property

Top-level object in the browser environment refers to the windowobjects in the Node refers to the globalobject.

Among ES5, the top-level object attributes and global variables are equivalent.

window.a = 1;
a // 1

a = 2;
window.a // 2

ES6 provisions

varCommand and functionglobal variables declared in command, is still property of the top-level object; letcommand, constcommand, classcommand declared a global variable, not part of the top-level object's properties

var a = 1;
// 如果在Node的REPL环境,可以写成global.a
// 或者采用通用方法,写成this.a
window.a // 1

let b = 1;
window.b // undefined

global objects

ES5's top-level object, in various implementations, there is not uniform.

  • Inside the browser, the top-level objects are window, but the Node and Web Worker no window.
  • Browsers and Web Worker inside, selfalso point to top-level object, but there is no Node self.
  • Node inside the top-level objects are global, but do not support other environments.

Barely two kinds In all cases, the method to get the top-level object

// 方法一
(typeof window !== 'undefined'
   ? window
   : (typeof process === 'object' &&
      typeof require === 'function' &&
      typeof global === 'object')
     ? global
     : this);

// 方法二
var getGlobal = function () {
  if (typeof self !== 'undefined') { return self; }
  if (typeof window !== 'undefined') { return window; }
  if (typeof global !== 'undefined') { return global; }
  throw new Error('unable to locate global object');
};

Guess you like

Origin www.cnblogs.com/bradleyxin/p/11693719.html