[译] 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> 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Implementing Responsive Design
Tim Kadlec / New Riders / 2012-7-31 / GBP 27.99
New devices and platforms emerge daily. Browsers iterate at a remarkable pace. Faced with this volatile landscape we can either struggle for control or we can embrace the inherent flexibility of the w......一起来看看 《Implementing Responsive Design》 这本书的介绍吧!