阮一峰ES6学习笔记

ES6的开发环境搭建

建立工程目录

先建立一个项目的工程目录,并在目录下边建立两个文件夹:scr和dist
* src:书写ES6代码的文件夹,写的js程序都放在这里
* dist:利用Bable编译成ES5代码的文件夹,在HTML页面需要引入这里的js文件

编写index.html:

文件夹建立好以后,新建一个index.html文件。

需要注意的是在引入js文件时,引入的是dist目录下的文件。

<script src="./dist/index.js"></script>

编写index.js

在scr目录下,新建index.js文件

let a = 1;
console.log(a);

初始化项目

打开终端或命令行公积进行初始化,默认全部同意

npm init -y

初始化完成后可根据自己的需求在package.json中修改初始化内容

全局安装Babel-cli

全局安装Bable的命令行

cnpm install -g babel-cli
本地安装babel-preset-es2015 和 babel-cli
cnpm install --save-dev babel-preset-es2015 babel-cli

安装完成后在package.json中会多出decDependencies选项

新建 .babelrc

在根目录下新建.babellrc文件,并打开录入以下代码

{
    "presets":[
        "es2015"
    ],
    "plugins":[]
}

建立完成后在终端输入

babel src/index.js -o dist/index.js

简化转化命令

在package.json中编写script字段

{
    "script":{
        "build":"babel src/index.js -o dist/index.js"
    }
}

修改好以后 直接可在命令行使用 npm run build 来进行转化


let和const命令

1.let命令

基本用法

ES6新增的let命令,用来声明变量,类似var,但是声明的变量,只在let声明的代码块中有效

{
    let a = 10;
    vat b = 9;
}

console.log(a);  //ReferenceError: a is not defined.
console.log(b);  //9

因为let的特性,在for循环中就更适合使用let命令

for (let a = 0; a < 10; a++) {
    //...
}
console.log(a);  //ReferenceError: a  is not defined.

上面的代码中a,只在for循环体内有效,在循环体外就报错。

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

上面的代码使用的var,最后输出的是10,变量i通过var声明,所以只有一个全局变量i.每次循环i都是改变值,而循环内被赋值给数组a的函数内部的console.log(i),里面的i指向的就是全局i,也就是说,所有数组a的成员里面的i,指向的都是同一个i,导致运行时输出的是最后一轮的i的值,也就是10。

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

上面代码中,变量ilet声明的,声明的变量仅在块级作用域内有效,最后输出的是6。当前的i只在本轮循环中有效,所以每次循环的i其实都是一个新的变量,所以最后输出的是6。每一次循环的变量i的值之所以会递增,这是因为JavaScript引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算的。

另外,for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。

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

上面代码正确运行,输出了3次abc。这表明函数内部的变量i与循环变量i不在同一个作用域,有各自单独的作用域。


不存在变量提升

var命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined。这种现象有点不是很合理。
为了纠正这种现象,let命令改变了语法行为,在声明之前只有就会报错。

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

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

暂时性死区

只要块级作用域内存在let命令,它所声明的变量就“绑定”在这个区域,不搜外面的影响。

var tem = 123;
if(true){
    tem = 'abc'; //ReferenceError
    let tem;
}

上面代码中,存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值会报错。
ES6 明确规定,如果区块中存在letconst命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

if (true) {
  // TDZ开始
  tmp = 'abc'; // ReferenceError
  console.log(tmp); // ReferenceError

  let tmp; // TDZ结束
  console.log(tmp); // undefined

  tmp = 123;
  console.log(tmp); // 123
}

typeof x; // ReferenceError
let x;

typeof undeclared_variable // "undefined"


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

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


// 不报错
var x = x;

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值