1.ECMAScript 6.0(以下简称ES6)。

2.ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的其中一种实现。

3.对ES6支持的浏览器:超过 90%的 ES6 语法特性都实现了。

4.Node(nodejs)是 JavaScript 的服务器运行环境(runtime)。

5.Babel 是一个广泛使用的 ES6 转码器,可以将 ES6 代码转为 ES5 代码。

npm install --save-dev @babel/core  //在项目目录中安装命令

(1)配置文件.babelrc,存放在项目的根目录下。用于设置转码规则和插件。所有 Babel 工具和模块的使用,都必须先写好.babelrc

//基本格式
{
"presets": [], //设定转码规则的:如安装官方提供的最新规则集:npm install --save-dev @babel/preset-env
"plugins": [] }

将新安装的规则加入.babelrc

  {
"presets": [
"@babel/env"
],
"plugins": []
}

(2)使用工具@babel/cli进行命令行转码

npm install --save-dev @babel/cli  //安装
#基本用法:

# 转码结果输出到标准输出
npx babel example.js # 转码结果写入一个文件
# --out-file 或 -o 参数指定输出文件
npx babel example.js --out-file compiled.js //单个文件转码输出到compiled.js
# 或者
npx babel example.js -o compiled.js # 整个目录转码
# --out-dir 或 -d 参数指定输出目录
npx babel src --out-dir lib //整个src目录转码输出到lib
# 或者
npx babel src -d lib # -s 参数生成source map文件
npx babel src -d lib -s

(3)@babel/node模块,实现ES6的REPL(Read Eval Print Loop:交互式解释器),可以直接运行ES6代码

npm install --save-dev @babel/node   //安装
npx babel-node  //进入REPL环境命令
npx babel-node
> (x => x * 2)(1) //直接执行表达式代码
2
# es6.js 的代码
# console.log((x => x * 2)(1));
npx babel-node es6.js //直接运行脚本文件
2

(4)使用@babel/register改写require命令。目的是每当使用require加载.js,.jsx,.es和.es6后缀的文件,会自动先用babel转码。它是实时转码,所以只适合在开发环境使用。

npm install --save-dev @babel/register  //安装

// index.js //在一个名为index.js的文件引入es6.js
require('@babel/register'); //要首先加载@babel/register
require('./es6.js'); //引入上面的es6.js文件 //使用
node index.js //直接执行es6.js中的es6代码,不需要手动对index.js转码

(5)babel API:如果代码需要调用babel API进行转码,那么需要用到@babel/core模块,参考这里

(6)使用@babel/polyfill,为当前环境提供垫片。babel默认只转换新的javas句法(syntax),不转换新的API,如Set,Map等全局对象都不会转码。

ES6在Array对象新增了Array.from方法。babel就不会进行转码,如果想运行这个方法,必须使用babel-polyfill。

http://babeljs.io/docs/usage/options/   //安装

//在脚本头部引入
import '@babel/polyfill';
// 或者
require('@babel/polyfill');

(7)使用@babel/standalone模块,将babel用于浏览器环境。

<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>  //将代码插入网页
<script type="text/babel">
// Your ES6 code
</script>

6.let 和 const 命令声明变量

(1)let

let 类似于var,但声明的变量只在所在的代码块内有效

{
let a = 10;
var b = 1;
} a // ReferenceError: a is not defined.
b //

for循环计数器中就很适合使用let命令

如下例子:

var a = [];
for (var i = 0; i < 10; i++) { //循环变量会泄露为全局变量
a[i] = function () {
console.log(i);
};
}
a[6](); //
var a = [];
for (let i = 0; i < 10; i++) { //let 声明的i每次循环都是一个从新声明的变量,不过javascript引擎内部会记住上一轮循环的值
a[i] = function () {
console.log(i);
};
}
a[6](); //

另外:

for (let i = 0; i < 3; i++) { //正确运行是会输出3次abc,函数内部变量i与循环变量i不在同一个作用域,各自有单独的作用域
let i = 'abc';
console.log(i);
}
// abc
// abc
// abc

let 不存在变量提升的问题(变量可以在声明之前使用)

// var 的情况
console.log(foo); // 输出undefined
var foo = 2; // let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;

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

var tmp = 123;

if (true) {
tmp = 'abc'; // ReferenceError,
let tmp; //在块中暂形成了tmp的封闭作用域tmp,使得tmp不受全局tmp影响,造成了tmp='abc'出现未定义先使用的错误
}
if (true) {
// TDZ开始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError let tmp; // TDZ结束
console.log(tmp); // undefined tmp = 123;
console.log(tmp); //
}

“暂时性死区”也意味着typeof不再是一个百分之百安全的操作。

typeof x; // ReferenceError
let x;

let 不允许在相同的作用域内重复声明同一变量for(var i =0;i<10;i++){a[i] = function(){console.log(i);}console.log(i);console.log(a[i]);console.log(a[i]())

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

let实际为javascript增加了块级作用域。有了块级作用域,使得原本广泛应用的立即执行函数表达式IIFE不再必要

// IIFE 写法
(function () {
var tmp = ...;
...
}()); // 块级作用域写法
{
let tmp = ...;
...
}

ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。ES5是不允许的,不过浏览器为了兼容旧代码,并不会报错。

考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句

ES6 的块级作用域必须有大括号,如果没有大括号,JavaScript 引擎就认为不存在块级作用域。

(2)const

const声明一个只读常量,一旦声明,值不能改变,所以一旦声明就要立即初始化

const PI = 3.1415;
PI // 3.1415 PI = 3; // TypeError: Assignment to constant variable.

const的作用域与let命令相同,块级内有效。

const声明的常量也不提升。

const声明同样存在暂时性死区TDZ。

const声明的常量也是不能重复。

const的本质:并不是变量的值不能改动,而是变量指向的那个内存地址所保存的数据不得改动。

对于简单类型:数值,字符串,布尔值,值就保存再变量指向的那个内存地址,因此等同于常量。

对于复杂类型:对象和数组,变量指向的内存地址,保存的只是一个指向实际数据的指针,保证的是指针不变,而指针指向的实际数据是可以改变的。

const foo = {};
// 为 foo 添加一个属性,可以成功
foo.prop = 123; //如果想禁止添加属性,将对象冻结,可以使用const foo = Object.freeze({})
foo.prop // 123 //使用冻结,在严格模式时,该语句会报错。 // 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only //对数组同理
const a = [];
a.push('Hello'); // 可执行
a.length = 0; // 可执行
a = ['Dave']; // 报错

除了对象冻结,也应将对象属性冻结,下面是将对象彻底冻结的函数

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

7.变量的解构赋值:从数组和对象中提取值,对变量赋值。

(1)

let a = 1;
let b = 2;
let c = 3; //以上等价于以下代码 let [a,b,c] = [1,2,3];
//属于模式匹配解构赋值
let [foo, [[bar], baz]] = [1, [[2], 3]];
foo //
bar //
baz // let [ , , third] = ["foo", "bar", "baz"];
third // "baz" let [x, , y] = [1, 2, 3];
x //
y // let [head, ...tail] = [1, 2, 3, 4];
head //
tail // [2, 3, 4] let [x, y, ...z] = ['a']; //
x // "a"
y // undefined
z // [] //解构不成功的,变量值就是undefined,如下都是:
let [foo] = [];
let [bar,foo] = [1]; //等同于let [bar,foo]=[1,],结果都是foo解构失败,为undefine
let [x, y] = [1, 2, 3];
x //
y // let [a, [b], d] = [1, [2, 3], 4];
a //
b //
d // 4
//以上是不完全解构

如果右边不是可遍历结构,将报错。

// 报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};

只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。

(2)

解构默认值

let [foo = true] = [];
foo // true let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
let [x = 1] = [undefined];
x // let [x = 1] = [null]; //因为null不严格等于undefined
x // null

(3)对象的解构赋值,与数组不一样的是,对象的解构赋值依据的属性同名,而数组依据的位置次序

let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"

这实际上说明,对象的解构赋值是下面形式的简写:

let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };
let { foo: baz } = { foo: 'aaa', bar: 'bbb' }; //foo是匹配模式,baz才是变量
baz // "aaa"
foo // error: foo is not defined

对象解构同样有默认值。

// 错误的写法
let x;
{x} = {x: 1};
// SyntaxError: syntax error

(4)字符串解构

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
let {length : len} = 'hello';
len //

还有数值布尔值解构,函数参数解构赋值。

(5)变量解构赋值用途

  • 交换变量的值
let x = 1;
let y = 2; [x, y] = [y, x];
  • 从函数返回多个值
// 返回一个数组

function example() {
return [1, 2, 3];
}
let [a, b, c] = example(); // 返回一个对象 function example() {
return {
foo: 1,
bar: 2
};
}
let { foo, bar } = example();
  • 函数参数的定义
// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]); // 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});
  • 提取JSON数据
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
}; let { id, status, data: number } = jsonData; console.log(id, status, number);
// 42, "OK", [867, 5309]
  • 函数参数的默认值//避免在函数体内再写var foo= config.foo ||'default'这样的语句
jQuery.ajax = function (url, {
async = true,
beforeSend = function () {},
cache = true,
complete = function () {},
crossDomain = false,
global = true,
// ... more config
} = {}) {
// ... do stuff
};
  • 遍历Map结构
const map = new Map();
map.set('first', 'hello');
map.set('second', 'world'); for (let [key, value] of map) {
console.log(key + " is " + value);
}
// first is hello
// second is world
//特别地
// 获取键名
for (let [key] of map) {
// ...
} // 获取键值
for (let [,value] of map) {
// ...
}
  • 输入模块的指定方法
const { SourceMapConsumer, SourceNode } = require("source-map")

https://www.cnblogs.com/libin-1/p/6716470.html

http://caibaojian.com/es6/

https://www.jianshu.com/p/87008f4f8513

https://www.runoob.com/w3cnote/es6-tutorial.html

http://es6.ruanyifeng.com/

ES6的基础知识(一)的更多相关文章

  1. es2015(es6)基础知识整理(更新中...)

    1.let let可以声明块级作用域变量 'use strict'; if (true) { let app = 'apple'; } console.log(app); //外面是访问不到app的 ...

  2. ES6的基础知识总结

    一. ES6 ES6中定义变量使用 let/const let 使用let定义的变量不能进行"变量提升" 同一个作用域中,let不能重复定义相同的变量名 使用var在全局作用域中定 ...

  3. es6 generator 基础知识

    1.定义和使用 function *gen() { return 'first generator'; } // 有点类似类的实例化过程 let generatorResult = gen() // ...

  4. javascript基础知识笔记-自用

    笔记内容根据个人基础知识不足不明白之处做的记录.主要看的:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript 1.变量,变量的名字又叫标识符 ...

  5. React Native 入门基础知识总结

    中秋在家闲得无事,想着做点啥,后来想想,为啥不学学 react native.在学习 React Native 时, 需要对前端(HTML,CSS,JavaScript)知识有所了解.对于JS,可以看 ...

  6. 快速掌握JavaScript面试基础知识(三)

    译者按: 总结了大量JavaScript基本知识点,很有用! 原文: The Definitive JavaScript Handbook for your next developer interv ...

  7. 快速掌握JavaScript面试基础知识(二)

    译者按: 总结了大量JavaScript基本知识点,很有用! 原文: The Definitive JavaScript Handbook for your next developer interv ...

  8. es 模块的基础知识,深度了解

    // 一模块的基础知识 /** * export :用于模块输出的出口 * import :文件引入的入口 */ // 1,第一种方式使用export方式输出 var a = 'a'; var b = ...

  9. java基础知识学习笔记

    本文知识点以js为参照.对比分析得出笔记.JavaScript之所以叫JavaScript是打算借助java推广自己.虽然都是开发语言,但JavaScript一开始主要运行在 客户端,而java主要运 ...

随机推荐

  1. 百万年薪python之路 -- Socket

    Socket 1. 为什么学习socket 你自己现在完全可以写一些小程序了,但是前面的学习和练习,我们写的代码都是在自己的电脑上运行的,虽然我们学过了模块引入,文件引入import等等,我可以在程序 ...

  2. Spring事务传播属性有那么难理解吗?

    学习东西要知行合一,如果只是知道理论而没实践过,那么掌握的也不会特别扎实,估计过几天就会忘记,接下来我们一起实践来学习Spring事务的传播属性. 传播属性 传播属性定义的是当一个事务方法碰到另一个事 ...

  3. day04整理

    目录 内容回顾 变量 什么是变量 变量的组成 变量名的命名规范 注释 单行注释 多行注释 turtle库的使用 一.数据类型基础 一.数字类型 (一)整形 (二)浮点型 二.字符串类型 (一)作用:姓 ...

  4. Javascript对this对象的理解

    在JavaScript中this表示函数运行的时候自动生成的一个内部对象,只能在函数内部使用,下面是一个简单的例子: function test(){ alert(this == window); } ...

  5. ThreadLocal小试牛刀

    ThreadLocal中保存的数据只能被当前线程私有,不被其它线程可见 证明 声明一个全局的变量threadLocal,初始值为1,通过3个线程对其进行访问修改设置,理论上threadLocal的最终 ...

  6. nginx原理和优化

    Nginx的模块与工作原理 Nginx由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端请求映射到一个location block(location是 ...

  7. 怎么用Vuecli 3.0快速创建项目

    一.安装 1.安装node.js,这里需要注意的是,Vue CLI 3需要 nodeJs ≥ 8.9,所以我们去中文官方下载地址:http://nodejs.cn/download/,下载最新版本即可 ...

  8. django & celery - 关于并发处理能力和内存使用的小结

    背景 众所周知,celery 是python世界里处理分布式任务的好助手,它的出现结合赋予了我们强大的处理异步请求,分布式任务,周期任务等复杂场景的能力. 然鹅,今天我们所要讨论的则是如何更好的在使用 ...

  9. sql中实现先排序后分组

    数据表结构和数据如下: CREATE TABLE `commun_message_chat_single` ( `id` ) NOT NULL AUTO_INCREMENT, `chat_id` ) ...

  10. ThinkCMF 框架上的任意内容包含漏洞

    0x01  背景 ThinkCMF是一款基于PHP+MYSQL开发的中文内容管理框架,底层采用ThinkPHP3.2.3构建. ThinkCMF提出灵活的应用机制,框架自身提供基础的管理功能,而开发者 ...