let command
Basic Usage
ES6 add, to declare variables, similar to the usage var
, the declared variable, only let
valid 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 i
is var
declared valid globally, so that only a global variable i
. In each cycle, the variable i
value will change, is assigned to the array within the loop a
of function
the run time, you will read the same through a variable closure i
, resulting in a final output of the final i
value, 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 i
is let
declared, the current i
is only valid in the current round of cycle, so every time cycle i
are in fact a new variable, the final output is 6
. You might ask, if the variable cycle of each round i
are 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 i
when it is calculated on the basis of a round-robin.
for
There 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 i
and the external variables i
are separated.
There is no variable lift
var
Command will happen "variable lift" phenomenon, that can be used before variable declarations, value undefined
.
let
Command 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 let
commands, 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 let
and const
command, 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 let
before the command to declare variables, the variables are not available. This is grammatically called "temporary dead zone"
"Temporary dead zone" also means that typeof
no 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
, const
the 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
let
Do 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
let
JavaScript 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 let
can 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 if
the function of the declaration f
will 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 let
treatment.
According to these three rules, ES6 environment in the browser, a function declared within a block-level role, behavior similar to var
variable 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 do
so that it becomes do
an expression.
let x = do {
let t = f();
t * t + 1;
};
const command
Basic Usage
const
Declare a read-only constant. Once the value of the statement, constants can not be changed, which means that const
once 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.
const
Scope and let
command the same: block-level role only in the region where it is declared effective.
const
Constant command statement is not the upgrade, there are also temporary dead zone, can only be used in the back position statement.
Nature
const
In 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, const
can 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 foo
stored in an address that points to an object. Immutable only this address, that is not the foo
point 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.freeze
the method.
const foo = Object.freeze({});
// 常规模式时,下面一行不起作用;
// 严格模式时,该行会报错
foo.prop = 123;
The above code, the constant foo
pointing 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 window
objects in the Node refers to the global
object.
Among ES5, the top-level object attributes and global variables are equivalent.
window.a = 1;
a // 1
a = 2;
window.a // 2
ES6 provisions
var
Command and function
global variables declared in command, is still property of the top-level object; let
command, const
command, class
command 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 nowindow
. - Browsers and Web Worker inside,
self
also point to top-level object, but there is no Nodeself
. - 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');
};