wdnmd

ES6标准入门 2/26

第一章

ECMAScript6 简介

1.首先经典开头,ECMAScript跟JavaScript的关系,前者是后者的规格,后者是前者的一种实现。在日常场合中,这两个词是可以互换的。

2.ES6可以泛指5.1版本以后的JavaScript。涵盖了ES2015,ES2016,ES2017等。该书中的ES6,一般指的是ES2015标准,但有时也泛指“下一代JavaScript语言”。

3.Babel是一个广为使用的ES6转码器,可以将ES6代码转为ES5代码,从而在浏览器或其他环境执行。

 

第二章

let和const命令

1.let声明的代码只在起所在代码块有效。

2.经典for循环

test1:因为let声明只在所在代码块有效。

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

 

test2:使用var声明

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

 

 因为变量i是var声明的,在全局范围内有效,所以全局只有一个变量i,赋给数组a的console.log(i)指向全局的i。也就是说,所有数组都指向同一个i。

test3:使用let声明

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

 

 变量i仅在本轮循环有效。所以每一次i其实都是一个新的变量,最后输出6.

如果每一次i都是重新声明的,那它怎么知道上一轮循环的值从而计算本轮循环的值呢?

这是因为Js引擎内部会记住上一轮循环的值,初始化本轮的变量为i时,就在上一轮循环的基础上进行计算。

3.不存在变量提升,var命令会发生变量提升的现象,即变量可以在声明之前使用,值为undefined。按照一般的逻辑,变量应该在声明语句之后才可以使用。

  为了纠正这种现象,let命令改变了语法行为,必须先声明后使用。

4.暂时性死区(temporal dead zone,简称TDZ)。 只要块级作用域内存在let命令,它所声明的变量就“绑定”这个区域,不在受外部的影响。

var tmp = 123;
if(true){
    tmp = 'abc';
    let tmp;
}

 

ES6明确规定,规定,规定。这是规定,难怪之前看文章很难理解这个,根本不需要理解,就是人家给的规定。

如果区块中存在let和const命令,则这个区块对这些命令声明的变量从一开始就形成封闭作用域。只要在声明之前使用这些变量,就会报错。

5.暂时性死区也意味着typeof不再是个百分百安全的操作;

如typeof x;//  ReferenceError

  let  x;

只要在死区,未声明前用了,就会报错。

6.就是要我们养成先声明后使用的习惯,没声明使用就会报错。

隐蔽死区例子

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

 

 调换位置即可,改成(x=2,y=x)

7.暂时性死区的本质:只要进入了当前作用域,所要使用的变量就已经存在,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用变量。

 8.块级作用域

ES5只有 全局作用域和函数作用域,没有块级作用域,这导致很多场景不合理

case1:内层变量可能会覆盖外层变量

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

以上代码的原意是if代码外部使用外层的tmp,内部使用内层的tmp。但是输出的是undefined,原因是变量提升,var tmp,tmp上升为全局变量,tmp往上面找,if是false进不去所以undefined。

case2:用来计数的循环变量泄漏为全局变量

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

 

 i只是用来控制循环,却泄漏成为了全局变量。

9.let实际上为javascript新增了块级作用域。

function f1(){
    let n=5;
    if(true){
    let n=10;
    console.log("内部n="+n)
    }
    console.log("外部n="+n)
}
f1();

 

 块级作用域的出现,使得广泛应用的立即执行匿名函数IIFE不在必要了。

10.const声明一个只读的常量。一旦声明,常量的值就不能改变,也就意味着,const一旦声明必须立即初始化。

const实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。

const foo = {};
foo.prop = 123;//可以
console.log(foo);
foo = {};

 

 11.Object.freeze 将对象冻结

const foo = Object.freeze({});
foo.prop = 123;//不起作用
console.log(foo);

 

 12.顶层对象的属性与全局变量相关,被认为是JavaScript语言中最大的设计败笔之一。

window.a = 1;
a // 1


a = 2;
window.a //2

无法在编译时就提示变量未声明的错误,只有运行时才知道;程序员很容易不知不觉创建全局对象(如打错字);顶层对象的属性是到处都可以读写,不利于模块化编程。

13.ES6开始,全局变量将逐步与顶层对象的属性隔离。

var a = 1;
window.a //1

let b = 1;
window.b//undefined

 

posted @ 2020-04-01 23:33  FreshChick  阅读(164)  评论(0编辑  收藏  举报