ES6标准入门(第3版)-笔记

准备工作

  1. 新建空工作文件夹
  2. 在该文件夹打开终端,并初始化项目,-y取默认配置,安装完毕出现package.json配置文件
    自动生成 package.json
$ npm init -y
  1. 后续可能需安装大量安装包,切换成淘宝镜像进行下载更快捷
#查看当前镜像源
$ npm get registry
#切换淘宝镜像,直接更换地址法
$ npm config set registry http://registry.npm.taobao.org/

1.6 Babel转码器

  1. 配置文件 .babelrc

格式:

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

presets字段设定转码规则,官方提供以下的规则集,按需安装

# 最新转码规则 
$ npm install --save-dev babel-preset-latest 
 
# react 转码规则 
$ npm install --save-dev babel-preset-react 
 
# 不同阶段语法提案的转码规则(共有4个阶段),选装一个 
$ npm install --save-dev babel-preset-stage-0 
$ npm install --save-dev babel-preset-stage-1 
$ npm install --save-dev babel-preset-stage-2 
$ npm install --save-dev babel-preset-stage-3 

配置规则:

{
        
	"presets": [      
	"latest",       
	"react",       
	"stage-2"     
	],    
	"plugins": []   
} 

注:后续babel相关工具和模块的使用,.babelrc配置好是前提

  1. 命令行转码babel-cli

安装命令:

#全局安装
$ npm install --global babel-cli

# 安装在项目中
$ npm install --save-dev babel-cli 

基本用法:

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

安装在项目中是改写package.json

{
      
	"devDependencies": {
        
		"babel-cli": "^6.0.0"   
	},   
	"scripts": {
   
		"build": "babel src -d lib"   
	}, 
}

转码时执行

$ npm run build
  1. babel-node
    babel-cli自带babel-node命令,提供REPL环境(可直接运行es6),执行"babel-node"直接进入REPL环境,或直接运行es6脚本——“babel-node es6.js”
    babel-cli安装在项目中时,package.json可配置如下:
{
      
	"scripts": {
        
		"script-name": "babel-node es6.js"   
	} 
}

"使用babel-node替代node,这样script.js本身就不用做任何转码处理" ——

  • node?不是babel?
  1. babel-register
    实时转码,适合开发环境 。当使用require加载 .js .jsx .es .es6 等文件时,该工具会将其自动转码,但不包括当前文件的转码

下载:

$ npm install --save-dev babel-register

使用:

require("babel-register");
require("./index.js");
  1. babel-core
    提供转码API

安装命令:

$ npm install babel-core --save 

使用:

var babel = require('babel-core'); 
 
// 字符串转码 
babel.transform('code();', options); // => { code, map, ast } 
 
// 文件转码(异步) 
babel.transformFile('filename.js', options, function(err, result) {
      result; // => { code, map, ast } }); 
 
// 文件转码(同步) 
babel.transformFileSync('filename.js', options); // => { code, map, ast } 
 
// Babel AST转码 
babel.transformFromAst(ast, code, options); // => { code, map, ast } 

举例:

var es6Code = 'let x = n => n + 1'; 
var es5Code = require('babel-core')   
	.transform(es6Code, {
        
	presets: ['latest']   
	})   
	.code; 
// '"use strict";\n\nvar x = function x(n) {\n  return n + 1;\n};' 
  1. babel-polyfill
    babel默认转换新的js语法,不转换新的API及一些定义在全局对象上的方法,使用babel-polyfill可对这些API和方法进行转码

安装:

$ npm install --save babel-polyfill 

使用:

import 'babel-polyfill'; 
// 或者 
require('babel-polyfill'); 

注:Babel 默认不转码的 API 非常多,详细清单可以查看babel-plugin-transform-runtime模块的definitions.js文件。

1.7 Traceur转码器

Traceur 允许将 ES6 代码直接插入网页
使用:

<script src="https://google.github.io/traceur-compiler/bin/traceur.js"></script> 
<script src="https://google.github.io/traceur-compiler/bin/BrowserSystem.js"></script> 
<script src="https://google.github.io/traceur-compiler/src/bootstrap.js"></script> 
<script type="module">   
	import './Greeter.js'; 
</script>

2.1 let

  1. 无变量提升,凡在let声明前使用,则报ReferenceError 错误 (var在声明前使用,值为undefined)
  2. 暂时性死区(TDZ) 在块级作用域中存在let命令,该变量就会绑定该区域,不受外部影响
var tmp=1;
if (true) {
      
	// TDZ开始   
	tmp = 'abc'; // ReferenceError   
	console.log(tmp); // ReferenceError 
 
	let tmp; // TDZ结束   
	console.log(tmp); // undefined 
	
	tmp = 123;   
	console.log(tmp); // 123 
}
暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
  1. 不允许重复声明

2.2 块级作用域

  1. 函数声明与块级作用域
    ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。但浏览器为兼容旧代码,不会报错
    ES6 规定:(仅在浏览器的ES6环境中有效,其他环境不用遵守,即将块级作用域的函数声明当作let处理)

     a. 块级作用域中,函数声明语句的行为类似 let,在块级作用域之外不可引用
     b. 允许在块级作用域内声明函数(包含在大括号 {} 中才成立)
     c. 函数声明会提升到所在作用域的头部,,类似 var
    

考虑到环境导致的行为差异太大,当需要在块级作用域中声明函数时,应采用函数表达式的形式,而不是函数声明语句

// 函数声明语句 
{
      
	let a = 'secret';   
	function f() {
        
		return a;   
	} 
} 
 
// 函数表达式 
{
      
	let a = 'secret';   
	let f = function () {
        
		return a;   
	}; 
}
  1. const 本质
    const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合型数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的。

    当需要将对象及其属性都变为常量(不可修改),应使用 Object.freeze 方法

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

2.4 顶层对象的获取

ES5的顶层对象在各种实现里面不统一:

顶层对象 window self global
浏览器 X
Node X X
web Worker X X

为了取到顶层对象,现在一般使用 this 变量,但有局限性

  • 全局环境中,this会返回顶层对象。但是,Node 模块和 ES6 模块中,this返回的是当前模块。
  • 函数里面的this,如果函数不是作为对象的方法运行,而是单纯作为函数运行,this会指向顶层对象。但是,严格模式下,这时this会返回 undefined。
  • 不管是严格模式,还是普通模式,new Function(‘return this’)(),总是会返回全局对象。但是,如果浏览器用了 CSP(Content Security Policy,内容安全政策),那么eval、new
    Function这些方法都可能无法使用。

以下两种方式勉强可以使用获取顶层对象:

// 方法一 
(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'); 
}; 

垫片库 system.global 模拟了一个提案,可以在所有环境拿到 global。

// CommonJS 的写法 
var global = require('system.global')(); 
 
// ES6 模块的写法 
import getGlobal from 'system.global'; 
const global = getGlobal(); 

3.1 解构赋值

  1. 数组的解构赋值,以元素的次序取值
  2. 对象的解构赋值,以元素的名称取值(可重新取名)
//注:
//p:匹配模式,
//name:真正赋值的变量
let {
    p : name}=obj;

const node = {
      
loc: {
        
start: {
          
line: 1,       
column: 5     }   } }; 
 
let {
    loc, loc: {
    start }, loc: {
    start: {
    line }} } = node; line // 1 loc  // Object {start: Object} start // Object {line: 1, column: 5} 
对象的解构赋值可以设置默认值,但生效条件是当对象的属性值严格等于 undefined
var {
   x = 3} = {
   x: undefined}; x // 3 
 
var {
   x = 3} = {
   x: null}; x // null 

解构赋值的规则是,只要等号右边的值不是对象或者数组,就先将其转为对象。由于 undefined 和 null 无法转为对象,所以对它们解构赋值会报错

let {
    prop: x } = undefined; // TypeError 
let {
    prop: y } = null; // TypeError 

变量声明语句不得使用圆括号——会引发歧义导致报错
赋值语句的非模式部分可以使用括号

4.2 codePointAt()

JavaScript 内部,字符以 UTF-16 的格式储存。\u0000~\uFFFF 之间的字符只表示 2 个字节的字符,超出 0xFFFF 的字符需要用 4 个字节表示
codePointAt 方法是测试一个字符由 2 个字节还是由 4 个字节组成的简单方法。其返回的是十进制码点,如需十六进制的值可用 toString 方法转换

let s = '𠮷a'; 
//for...of 可以正确识别 32 位的 UTF-16 字符,即识别大于0xFFFF的码点
for (let ch of s) {
      
	console.log(ch.codePointAt(0).toString(16)); 
} 
// 20bb7 // 61 

function is32Bit(c) {
      
	return c.codePointAt(0) > 0xFFFF; 
}  
is32Bit("𠮷") // true 
is32Bit("a") // false 

与 codePointAt 相反的操作是:将码点返回对应的字符,可用 String.fromCodePoin 方法

注:fromCodePoint方法定义在String对象上,而codePointAt方法定义在字符串的实例对象上。

4.7 includes(), startsWith(), endsWith(),repeat(),padStart(),padEnd()

  • includes():返回布尔值,表示是否找到了参数字符串。
  • startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
  • endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
    第一个参数表示要查找的字符,第二个可选参数表示开始搜索的位置
let s = 'Hello world!'; 
 
s.startsWith('world', 6) // true 
s.endsWith('Hello', 5) // 
true s.includes('Hello', 6) // false 
  • repeat方法返回一个新字符串,表示将原字符串重复n次
  • padStart()用于头部补全
  • padEnd()用于尾部补全
//参数表示重复n次
'x'.repeat(3) // "xxx" 

//第一个参数表示总字符串长度
//第二个可选参数表示需要补全的字符,无则补空
'x'.padStart(5, 'ab') // 'ababx' 
'x'.padEnd(5, 'ab'
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值