[译] You Might Not Use ES6
栏目: JavaScript · 发布时间: 5年前
内容简介:与函数表达式相比,箭头函数表达式(也称为胖箭头函数)的语法更简介,并且不会创建自己的箭头函数相当于匿名函数。ES6:
箭头函数
与函数表达式相比,箭头函数表达式(也称为胖箭头函数)的语法更简介,并且不会创建自己的 this
。
箭头函数相当于匿名函数。
ES6:
[1, 2, 3].map(n => n * 2); // -> [ 2, 4, 6 ] 复制代码
ES5 实现:
[1, 2, 3].map(function(n) { return n * 2; }, this); // -> [ 2, 4, 6 ] 复制代码
ES6:
var evens = [2, 4, 6, 8, 10]; // 表达式正文 var odds = evens.map(v => v + 1); var nums = evens.map((v, i) => v + i); console.log(odds); // -> [3, 5, 7, 9, 11] console.log(nums); // -> [2, 5, 8, 11, 14] // 声明式正文 var fives = []; nums = [1, 2, 5, 15, 25, 32]; nums.forEach(v => { if (v % 5 === 0) fives.push(v); }); console.log(fives); // -> [5, 15, 25] // 作用域中的 this var bob = { _name: 'Bob', _friends: [], printFriends() { this._friends.forEach(f => console.log(this._name + ' knows ' + f)); } } 复制代码
ES5:
'use strict'; var evens = [2, 4, 6, 8, 10]; // 表达式正文 var odds = evens.map(function (v) { return v + 1; }, this); var nums = evens.map(function (v, i) { return v + i; }, this); console.log(odds); // -> [3, 5, 7, 9, 11] console.log(nums); // -> [2, 5, 8, 11, 14] var fives = []; nums = [1, 2, 5, 15, 25, 32]; // 声明式正文 nums.forEach(function (v) { if (v % 5 === 0) { fives.push(v); } }, this); console.log(fives); // -> [5, 15, 25] // Lexical this var bob = { _name: 'Bob', _friends: [], printFriends: function printFriends() { this._friends.forEach(function (f) { return console.log(this._name + ' knows ' + f); }, this); } }; 复制代码
块级作用域函数
块作用域绑定提供了函数和顶级作用域以外的作用域。
这确保你的变量不会超出他们定义的范围内。
ES6:
// let 声明一个局部块作用域,在 ES6 中可以任意的初始化一个值 'use strict'; var a = 5; var b = 10; if (a === 5) { let a = 4; // 作用域在 if 块中 var b = 1; // 作用域在函数内部 console.log(a); // 4 console.log(b); // 1 } console.log(a); // 5 console.log(b); // 1 复制代码
ES5:
'use strict'; var a = 5; var b = 10; if (a === 5) { // 在实现上更像下面这样 (function () { var a = 4; b = 1; console.log(a); // 4 console.log(b); // 1 })(); } console.log(a); // 5 console.log(b); // 1 复制代码
ES6:
// const 在 ES6 中创建只读的属性常量 'use strict'; // 将 favorite 定义为常量并且赋值为 7 const favorite = 7; // 试图覆盖常量 try { favorite = 15; } catch (err) { console.log('my favorite number is still: ' + favorite); // 仍然会输出 7 } 复制代码
ES5:
'use strict'; // 将 favorite 定义为一个不可写的“常量”,并将其赋值为 7。 Object.defineProperties(window, { favorite: { value: 7, enumerable: true } }); // 属性描述默认为 false,并且 const 是可枚举的 var favorite = 7; // 试图覆盖常量 favorite = 15; // 仍然会输出 7 console.log('my favorite number is still: ' + favorite); 复制代码
模版字符串
ES6 模版字符串是可以包含 嵌入表达式 的字符串,有时也被叫做 插值表达式 。
ES6:
// 表达式占位符的基本用法 var person = 'Addy Osmani'; console.log(`Yo! My name is ${person}!`); // 表达式也可以用在对象中 var user = {name: 'Caitlin Potter'}; console.log(`Thanks for getting this into V8, ${user.name}.`); // 插值表达式:作用之一可以用来计算 var a = 50; var b = 100; console.log(`The number of JS frameworks is ${a + b} and not ${2 * a + b}.`); // 多行字符串不需要换行符 console.log(`string text line 1 string text line 2`); // 函数内部表达式 function fn() { return 'result'; } console.log(`foo ${fn()} bar`); 复制代码
ES5:
'use strict'; // 表达式占位符的基本用法 var person = 'Addy Osmani'; console.log('Yo! My name is ' + person + '!'); // 表达式也可以用在对象中 var user = { name: 'Caitlin Potter' }; console.log('Thanks for getting this into V8, ' + user.name + '.'); // 插值表达式:作用之一可以用来计算 var a = 50; var b = 100; console.log('The number of JS frameworks is ' + (a + b) + ' and not ' + (2 * a + b) + '.'); // 多行字符串 console.log('string text line 1\nstring text line 2'); // 或者下面这种写法 console.log('string text line 1\n\ string text line 2'); // 函数内部表达式 function fn() { return 'result'; } console.log('foo ' + fn() + ' bar'); 复制代码
计算属性
计算属性名允许你基于表达式在对象文本中指定属性
ES6:
var prefix = 'foo'; var myObject = { [prefix + 'bar']: 'hello', [prefix + 'baz']: 'world' }; console.log(myObject['foobar']); // -> hello console.log(myObject['foobaz']); // -> world 复制代码
ES5:
'use strict'; var prefix = 'foo'; var myObject = {}; myObject[prefix + 'bar'] = 'hello'; myObject[prefix + 'baz'] = 'world'; console.log(myObject['foobar']); // -> hello console.log(myObject['foobaz']); // -> world 复制代码
解构赋值
解构赋值语法是一个 JavaScript
表达式,它可以使用数组映射和对象文本构造的语法从数组和对象中提取值,对变量进行赋值。
ES6:
var {foo, bar} = {foo: 'lorem', bar: 'ipsum'}; // foo => lorem and bar => ipsum 复制代码
ES5:
'use strict'; var _ref = { foo: 'lorem', bar: 'ipsum' }; // foo => lorem and bar => ipsum var foo = _ref.foo; var bar = _ref.bar; 复制代码
ES3:
with({foo: 'lorem', bar: 'ipsum'}) { // foo => lorem and bar => ipsum } 复制代码
ES6:
var [a, , b] = [1,2,3]; 复制代码
ES6 (shimming using Symbol.iterator
):
'use strict'; var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) { break; } } return _arr; } }; var _ref = [1, 2, 3]; var _ref2 = _slicedToArray(_ref, 3); var a = _ref2[0]; var b = _ref2[2]; 复制代码
ES5:
String.prototype.asNamedList = function () { return this.split(/\s*,\s*/).map(function (name, i) { return name ? ('var ' + name + '=slice(' + i + ', ' + (i + 1) + ')[0]') : ''; }).join(';'); }; with([1,2,3]) { eval('a, , b'.asNamedList()); } 复制代码
默认参数
默认参数允许函数具有可选参数,而不需要检查参数的长度或是否未定义。
ES6:
function greet(msg='hello', name='world') { console.log(msg,name); } greet(); // -> hello world greet('hey'); // -> hey world 复制代码
ES5:
'use strict'; function greet() { // 如果像这样访问 arguments[0],则可以简单地进行访问 msg 变量名 var msg = arguments[0] === undefined ? 'hello' : arguments[0]; var name = arguments[1] === undefined ? 'world' : arguments[1]; console.log(msg, name); } function greet(msg, name) { (msg === undefined) && (msg = 'hello'); (name === undefined) && (name = 'world'); console.log(msg,name); } // 对未定义的参数进行检查的基本方法 function greet(msg, name) { console.log( defaults(msg, 'hello'), defaults(name, 'world') ); } greet(); // -> hello world greet('hey'); // -> hey world 复制代码
ES6:
function f(x, y=12) { // y 的指是 12 如果没有接收(或者接收的是 undefined ) return x + y; } f(3) === 15; 复制代码
ES5:
'use strict'; function f(x, y) { if (y === undefined) { y = 12; } return x + y; } f(3) === 15; 复制代码
Iterators 和 For-Of 循环
遍历器是可以遍历容器的对象。这是一种使类工作在 for..of
循环的有用方法。
接口类似于遍历器接口。
迭代一个 for..of
循环的形式如下。
ES6:
// 当前环境,将从数组中获取一个遍历器,并对其进行循环,从中获取值 for (let element of [1, 2, 3]) { console.log(element); } // => 1 2 3 复制代码
ES6 (without using for-of
, if Symbol
is supported):
'use strict'; for (var _iterator = [1, 2, 3][Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { var element = _step.value; console.log(element); } // => 1 2 3 复制代码
ES5 (approximates):
// 使用 forEach() // 不需要在包含的范围中声明索引和元素变量。它们被作为参数提供给遍历器,并被限定在遍历的范围内。 var a = [1,2,3]; a.forEach(function (element) { console.log(element); }); // => 1 2 3 // 使用 for 循环 var a = [1,2,3]; for (var i = 0; i < a.length; ++i) { console.log(a[i]); } // => 1 2 3 复制代码
注意 Symbol
的使用。ES5 需要一个正确的 Symbol polyfill
才能正常使用。
Class
class
实现了 ES6 规范草案中描述的类语法和语义。
class
是复用代码最好的方法。
一些 JS 库提供了类和继承,但它们并不相互兼容。
ES6:
class Hello { constructor(name) { this.name = name; } hello() { return 'Hello ' + this.name + '!'; } static sayHelloAll() { return 'Hello everyone!'; } } class HelloWorld extends Hello { constructor() { super('World'); } echo() { alert(super.hello()); } } var hw = new HelloWorld(); hw.echo(); alert(Hello.sayHelloAll()); 复制代码
ES5 ( 类似功能 ):
function Hello(name) { this.name = name; } Hello.prototype.hello = function hello() { return 'Hello ' + this.name + '!'; }; Hello.sayHelloAll = function () { return 'Hello everyone!'; }; function HelloWorld() { Hello.call(this, 'World'); } HelloWorld.prototype = Object.create(Hello.prototype); HelloWorld.prototype.constructor = HelloWorld; HelloWorld.sayHelloAll = Hello.sayHelloAll; HelloWorld.prototype.echo = function echo() { alert(Hello.prototype.hello.call(this)); }; var hw = new HelloWorld(); hw.echo(); alert(Hello.sayHelloAll()); 复制代码
更详细的介绍可以查看Babel
Modules
模块功能大部分是实现了,一些加载api仍然在改进中。
模块试图解决依赖关系和部署中的许多问题,允许用户使用显式导出创建模块,从这些模块中导入特定的导出名称,并保持这些名称的独立性。
app.js - ES6
import math from 'lib/math'; console.log('2π = ' + math.sum(math.pi, math.pi)); 复制代码
app.js - ES5
var math = require('lib/math'); console.log('2π = ' + math.sum(math.pi, math.pi)); 复制代码
lib/math.js - ES6
export function sum(x, y) { return x + y; } export var pi = 3.141593; 复制代码
lib/math.js - ES5
exports.sum = sum; function sum(x, y) { return x + y; } var pi = exports.pi = 3.141593; 复制代码
lib/mathplusplus.js - ES6
export * from 'lib/math'; export var e = 2.71828182846; export default function(x) { return Math.exp(x); } 复制代码
lib/mathplusplus.js - ES5
var Math = require('lib/math'); var _extends = function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { target[key] = source[key]; } } return target; }; var e = exports.e = 2.71828182846; exports['default'] = function (x) { return Math.exp(x); }; module.exports = _extends(exports['default'], exports); 复制代码
数字字面量
ES6:
var binary = [ 0b0, 0b1, 0b11 ]; console.assert(binary === [0, 1, 3]); var octal = [ 0o0, 0o1, 0o10, 0o77 ]; console.assert(octal === [0, 1, 8, 63]); 复制代码
ES5:
'use strict'; var binary = [0, 1, 3]; console.assert(binary === [0, 1, 3]); var octal = [0, 1, 8, 63]; console.assert(octal === [0, 1, 8, 63]); 复制代码
属性赋值方法
对象中支持方法语法, 比如说 toString()
ES6:
var object = { value: 42, toString() { return this.value; } }; console.log(object.toString() === 42); // -> true 复制代码
ES5:
'use strict'; var object = { value: 42, toString: function toString() { return this.value; } }; console.log(object.toString() === 42); // -> true 复制代码
对象属性的简介表示
在对象中的属性名和属性值相同时可以忽略属性值。
ES6:
function getPoint() { var x = 1; var y = 10; return {x, y}; } console.log(getPoint() === { x: 1, y: 10 }); 复制代码
ES5:
'use strict'; function getPoint() { var x = 1; var y = 10; return { x: x, y: y }; } console.log(getPoint() === { x: 1, y: 10 }); 复制代码
Rest 参数
rest
参数允许函数在不使用 arguments
对象的情况下具有可变数量的参数。
rest
参数是数组的一个实例,因此所有的数组方法都可以使用。
ES6:
function f(x, ...y) { // y 是个数组 return x * y.length; } console.log(f(3, 'hello', true) === 6); // -> true 复制代码
ES5:
'use strict'; function f(x) { var y = []; y.push.apply(y, arguments) && y.shift(); // y 是个数组 return x * y.length; } console.log(f(3, 'hello', true) === 6); // -> true 复制代码
扩展运算符
扩展运算符是和 rest
参数相反的。
它允许将数组展开为多个形式的参数。
ES6:
function add(a, b) { return a + b; } let nums = [5, 4]; console.log(add(...nums)); 复制代码
ES5:
'use strict'; var _toArray = function (arr) { return Array.isArray(arr) ? arr : [].slice.call(arr); }; function add(a, b) { return a + b; } var nums = [5, 4]; console.log(add.apply(null, _toArray(nums))); 复制代码
ES6:
function f(x, y, z) { return x + y + z; } // 传递数组的每一个参数 f(...[1,2,3]) === 6; 复制代码
ES5:
'use strict'; function f(x, y, z) { return x + y + z; } // 传递数组的每一个参数 f.apply(null, [1, 2, 3]) === 6; 复制代码
Proxy
ES6:
var target = function () { return 'I am the target'; }; var handler = { apply: function (receiver, ...args) { return 'I am the proxy'; } }; var p = new Proxy(target, handler); console.log(p() === 'I am the proxy'); // -> true 复制代码
ES5:
在 ES5 中没有 proxy
, 没有类似的方法去拦截。
类数组
Array.from使有着单一的参数类数组或者列表(像: arguments
, NodeList
, DOMTokenList
(当做 classList
), NamedNodeMap
(属性使用))返回一个新的数组实例。
ES6:
var listFriends = function() { var friends = Array.from(arguments); friends.forEach(friend => { console.log(friend); }); }; listFriends('ann', 'bob'); // -> 'ann' // -> 'bob' var divs = document.querySelectorAll('div'); Array.from(divs).forEach(node => { console.log(node); }); // -> <div>...</div> // -> <div>...</div> 复制代码
ES5:
var listFriends = function() { var friends = [].slice.call(arguments) friends.forEach(function(friend) { console.log(friend); }); }; listFriends('ann', 'bob'); // -> 'ann' // -> 'bob' var divsArray = [].slice.call(document.querySelectorAll('div')); divsArray.forEach(function(node) { console.log(node); }); // -> <div>...</div> // -> <div>...</div> 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
ANSI Common Lisp
Paul Graham / Prentice Hall / 1995-11-12 / USD 116.40
For use as a core text supplement in any course covering common LISP such as Artificial Intelligence or Concepts of Programming Languages. Teaching students new and more powerful ways of thinking abo......一起来看看 《ANSI Common Lisp》 这本书的介绍吧!