soket.io.js_io.js中的ES6

soket.io.js

io.js - the famous Node.js fork recently put out their initial release touting the slogan "Bringing ES6 to the Node Community!". io.js got these features ahead of Node.js by aggressively following the latest versions of the V8 JavaScript engine. As an outsider looking in, I took a few hours to poke around, and shall report my findings here.

io.js-著名的Node.js分支最近发布了其初始版本,并吹嘘“将ES6带入Node社区!”的口号。 io.js通过积极遵循最新版本的V8 JavaScript引擎,使这些功能领先于Node.js。 作为局外人,我花了几个小时在附近闲逛,并将在这里报告我的发现。

安装 (Installation)

Binary distributions of io.js are available from their front page, and you can download a binary for Linux, Windows, Mac, or build it from source. However, the binary installers will overwrite the node and npm executables on your system if you have Node.js installed. Therefore, I recommend using nvm to install io.js in a conflict-free way. Installing nvm is quite easy if you haven't done it before. If and when you have nvm, simply do

io.js的二进制发行版可从其首页获得 ,您可以下载Linux,Windows,Mac的二​​进制版本,也可以从源代码构建它。 但是,如果安装了Node.js,二进制安装程序将覆盖系统上的nodenpm可执行文件。 因此,我建议使用nvm以无冲突的方式安装io.js。 如果您以前没有安装过nvm,则安装它非常容易 。 如果并且当您拥有nvm时,只需执行

$ nvm install io.js
######################################################################## 100.0%
WARNING: checksums are currently disabled for io.js
Now using io.js v1.0.3


Check that it worked:

检查它是否有效:

$ iojs
>


Voilà! Note that node is aliased to iojs, and npm is still called npm.

瞧! 请注意, node别名为iojsnpm仍称为npm

ES6功能概述 (ES6 Features Overview)

Although some folks have already been using ES6 for a while via transpilers, when I work with transpiled code, it feels like I am having to simultaneously debug two versions of the code - debugging is hard enough with just one version. For this reason, having native support makes it much more appealing for me.

虽然有些 已经 已经 使用 ES6经由transpilers了一会儿,当我和transpiled代码工作,感觉就像我有同时调试代码的两个版本- 调试比较辛苦只有一个版本 。 因此,获得本地支持对我来说更具吸引力。

The io.js ES6 page gives information about the changes they've made to the ES6 support in the engine. They have done away with the --harmony flag - which in Node 0.11+ you had to include if you wanted to use any ES6 features at all. In io.js, you get them right out of the box! The current list of ES6 features enabled by default are:

io.js ES6页面提供了有关它们对引擎中的ES6支持所做的更改的信息。 他们已经取消了--harmony标志-如果您想完全使用任何ES6功能,则必须在--Node 0.11+中包括该标志。 在io.js中,您可以立即使用它们! 默认情况下,当前启用的ES6功能列表如下:

  • let statement

    let声明

  • const statement

    const陈述式

  • Map and Set

    MapSet

  • WeakMap and WeakSet

    WeakMapWeakSet

  • Generators

    发电机
  • Binary and Octal literals

    二进制和八进制文字
  • Promises

    承诺
  • Some additional string methods

    其他一些字符串方法
  • Symbols

    符号
  • Template strings

    模板字符串

They also added the --es_staging flag which would allow you to gain access to features that are done but haven't been well tested yet. For features that are in progress of being implemented, you'd have to gain access to each feature individually by using the harmony flag corresponding to it. You can get the list of harmony feature flags via:

他们还添加了--es_staging标志,该标志使您可以访问已完成但尚未经过良好测试的功能。 对于正在实施的功能,您必须使用与之对应的和声标记来单独访问每个功能。 您可以通过以下方式获取和声特征标记的列表:

$ iojs --v8-options|grep "harmony"
  --es_staging (enable all completed harmony features)
  --harmony (enable all completed harmony features)
  --harmony_shipping (enable all shipped harmony fetaures)
  --harmony_modules (enable "harmony modules (implies block scoping)" (in progress))
  --harmony_arrays (enable "harmony array methods" (in progress))
  --harmony_array_includes (enable "harmony Array.prototype.includes" (in progress))
  --harmony_regexps (enable "harmony regular expression extensions" (in progress))
  --harmony_arrow_functions (enable "harmony arrow functions" (in progress))
  --harmony_proxies (enable "harmony proxies" (in progress))
  --harmony_sloppy (enable "harmony features in sloppy mode" (in progress))
  --harmony_unicode (enable "harmony unicode escapes" (in progress))
  --harmony_tostring (enable "harmony toString")
  --harmony_numeric_literals (enable "harmony numeric literals")
  --harmony_strings (enable "harmony string methods")
  --harmony_scoping (enable "harmony block scoping")
  --harmony_classes (enable "harmony classes (implies block scoping & object literal extension)")
  --harmony_object_literals (enable "harmony object literal extensions")
  --harmony_templates (enable "harmony template literals")


Now, let's drill down to the individual features.

现在,让我们深入研究各个功能。

letconst (let and const)

The let and const statements are only available in strict mode. So put "use strict" at the top of each JS file where you wish to use them.

letconst语句仅在严格模式下可用。 因此,在每个要使用它们的JS文件的顶部放置"use strict"

The let statement is a replacement for the var statement which has lexical scoping. What this means is that while a variable defined with var is visible to the function within which it is declared, let is visible only to the code block within which it is declared. In JavaScript, a code block is a compound statement enclosed in { and } that contains zero or more statements. You commonly use code blocks within if-statements, for loops, while loops, and as the body of a function definition. But, it's also possible to write a standalone code block.

let语句代替了具有词法作用域的var语句。 这意味着,虽然用var定义的变量在声明该变量的函数中可见,但let仅在声明该变量的代码块中可见。 在JavaScript中, 代码块是包含在{}中的复合语句,其中包含零个或多个语句。 您通常在if语句,for循环,while循环以及函数定义的主体中使用代码块。 但是,也可以编写一个独立的代码块。

Here is an example of let:

这是let的示例:

"use strict"
if (player.partner){
  let partner = player.partner
  // do stuff with partner here
}
console.log(parter) // this throws partner is not defined


Here is let in a for loop:

这里是let在for循环中:

"use strict"
for (let i = 0; i < 10; i++){
  console.log(i)
}
console.log(i) // this throws i is not defined


const is like let except that once declared, the variable cannot be reassigned to another value.

const就像let一样,只不过一旦声明,就不能将变量重新分配给另一个值。

"use strict"
const ITERATIONS_TO_RUN = 10
ITERATIONS_TO_RUN = 12 // throws TypeError: Assignment to constant variable.


地图和设置 (Map and Set)

ES6 has introduced the Map and Set data structures for your convinience. Now you might be wondering, why do we even need a map? What's wrong with using object literals as maps? Well, it's been argued that an object is not a hash (or er map). The short version is that an object inherits all of Object.prototype's properties, which in most cases is unwanted if you want to use it as a map.

ES6引入了MapSet数据结构以方便您使用。 现在您可能想知道,为什么我们甚至需要一张地图? 使用对象文字作为映射有什么问题? 好吧,有人争辩说, 对象不是哈希(或er映射) 。 简短的版本是对象继承了Object.prototype的所有属性,如果您想将其用作地图,则在大多数情况下是不需要的。

Now, here's an example of using Map:

现在,这是使用Map的示例:

> var m = new Map
undefined
> m.set('name', 'Bobby')
{}
> m.get('name')
Bobby
> m.size
1
> m.set('age', 5)
{}
> m.has('age')
true
> m.has('foobar')
false
> m.forEach(function(value, key){ console.log(key + ' maps to ' + value) })
name maps to Bobby
age maps to 5
> m.get('hasOwnProperty') // avoids the `hasOwnProperty` trap
undefined
> m.clear()
undefined
> m.size
0


And here is Set in action:

这就是行动:

> var s = new Set
undefined
> s.add(1)
{}
> s.size
1
> s.add(2)
{}
> s.size
2
> s.add(1) // adding a duplicate here
{}
> s.size   // no change in size
2
> s.has(1)
true
> s.has(2)
true
> s.has(3)
false
> s.forEach(function(n){ console.log('Set has ' + n) })
Set has 1
Set has 2


WeakMap和WeakSet (WeakMap and WeakSet)

WeakMap and WeakSet are new data types that mirror Map and Set, but unlike Map and Set - which can be implemented as polyfills - these can only be implemented natively. The word "weak" refers to weak references. A weak reference is an object reference that is ignored by the garbage collector. If there exists only weak references - no more strong references - pointing to the object in question, then that object can be destroyed and its memory relinquished.

WeakMapWeakSet是反映MapSet新数据类型,但与MapSet不同-它们可以实现为polyfills-这些只能本地实现。 单词“弱”指的是弱引用弱引用是垃圾回收器忽略的对象引用。 如果仅存在弱引用(不再有强引用)指向所讨论的对象,则可以销毁该对象并放弃其内存。

Let's talk about WeakSet first - because it is easier to explain. A WeakSet's API is a subset of Set's. However, you cannot store primitive values in it:

首先让我们谈谈WeakSet因为它更容易解释。 WeakSet的API是Set的子集。 但是,您不能在其中存储原始值:

> var ws = new WeakSet
undefined
> ws.add(1)
TypeError: Invalid value used in weak set


This makes sense because primitive values are stored by value, not by reference, and it would make no sense to even speak of weak references. So, you'll need to put objects in it instead:

这是有道理的,因为原始值是按值存储的,而不是按引用存储的,甚至说弱引用也没有意义。 因此,您需要在其中放置对象:

> var bob = {name: 'Bob'}
undefined
> var jen = {name: 'Jen'}
undefined
> ws.add(bob)
{}
> ws.add(jen)
{}
> ws.has(bob)
true
> ws.has(jen)
true
> var jim = {name: 'Jim'}
undefined
> ws.has(jim)
false
> ws.delete(jen)
true
> ws.has(jen)
false


WeakSet has no size property, or a way of iterating its members

WeakSet没有size属性,或者是一种迭代其成员的方法

> ws.size
undefined
> ws.forEach(function(item){ console.log('WeakSet has ' + item)})
TypeError: undefined is not a function
> ws.forEach
undefined


This is precisely because the references are weak, and as such, the objects could be destroyed without notice, at which point it would be impossible to access them anymore. One possible use of WeakSet is to store a set of related DOM elements without worry of memory leaks when the elements are removed from the document.

正是因为引用很弱,所以对象可能会在没有通知的情况下被破坏,这时将无法再访问它们。 WeakSet一种可能用途是存储一组相关的DOM元素,而不必担心从文档中删除元素时会发生内存泄漏。

A WeakMap is like Map except that all of its keys are weak references. They also must not be primitive values.

WeakMap类似于Map除了它的所有键都是弱引用。 它们也不能是原始值。

var wm = new WeakMap
> var person = {name: 'Bob'}
undefined
> var creditCard = {type: 'AMEX', number: 123456789}
undefined
> wm.set(person, creditCard)
{}
> wm.get(person)
{ type: 'AMEX', number: 123456789 }


As with Set, there is no way to get the size of the WeakMap or iterate over it's keys or values:

与Set一样,无法获取WeakMap的size或对其键或值进行迭代:

> wm.size
undefined
> wm.forEach
undefined


When the application ceases to hold a strong reference to person, its entry in wm could be destroyed, and creditCard could in turned be destroyed as well. Read more about WeakMap and WeakSet.

当应用程序不再对person拥有强烈引用时,它在wm条目可能会被破坏,而creditCard也可能被破坏。 阅读有关WeakMapWeakSet的更多信息。

for-of (for-of)

In addition to the classic for-in statement, ES6 has added the for-of statement which allows you to succiently iterate the values of arrays, iterables, and generators. The latter two to be discussed below.

除了经典的for-in语句外,ES6还添加了for-of语句,该语句可让您简洁地迭代数组,可迭代对象和生成器的值。 后两个将在下面讨论。

Here is for-of iterating over an array:

下面是for-of迭代数组:

> var arr = [1, 2, 3]
undefined
> for (var n of arr) console.log(n)
1
2
3


可迭代和迭代器 (Iterables and Iterators)

So, you can also use the for-of statement to iterate over iterables.

因此,您还可以使用for-of语句对可迭代对象进行迭代。

But what is an iterable?

但是什么是可迭代的?

An iterable is an object that has an associated method which initializes and returns an iterator. The way you associate this method with an object is:

可迭代对象是具有关联方法的对象,该方法初始化并返回迭代器。 将此方法与对象关联的方式是:

var myObj = {}
myObj[Symbol.iterator] = function(){  // I'll cover symbols later
  return new MyIterator
} 


But what is an iterator?

但是什么是迭代器?

An iterator is an object that adheres to the iterator protocol - which requires simply one method:

迭代器是遵循迭代器协议的对象-仅需要一种方法:

  • next() - which advances to the next item in the sequence each time it is called and returns an object that contains two properties

    next() -每次调用时前进到序列中的下一项,并返回包含两个属性的对象

  • done - a boolean which is true if and only if the sequence has already ended

    done一个布尔值,当且仅当序列已结束时,它为true

  • value - the current value in the sequence

    value序列中的当前值

As an example, below is how I've managed to make a simple custom link list implementation iterable:

例如,以下是我设法使一个简单的自定义链接列表实现可迭代的方法:

function LLNode(value){
  this.value = value
  this.next = null
}
LLNode.prototype[Symbol.iterator] = function(){
  var iterator = {
    next: next
  }
  var current = this
  function next(){
    if (current){
      var value = current.value
      var done = current == null
      current = current.next
      return {
        done: done,
        value: value
      }
    }else{
      return {
        done: true
      }
    }
  }
  return iterator
}

var one = new LLNode(1)
var two = new LLNode(2)
var three = new LLNode(3)
one.next = two
two.next = three

for (var i of one){
  console.log(i)
}


The output of this program is

该程序的输出是

1
2
3


发电机 (Generators)

Generators allow you to write an iterable in a succient and easily understandable manner. It also allows you to represent infinite sequences.

生成器允许您以简洁易懂的方式编写可迭代的代码。 它还允许您表示无限序列。

Here is how I could write a generator that iterates all integers starting from 0:

这是我写一个生成器的方法,该生成器迭代从0开始的所有整数:

function *naturalNumbers(){
  var n = 0
  while (true){
    yield n++
  }
}


Note the function * syntax and the yield statement - these indicate that this is a generator function rather than a normal function. When you call a generator function, you get back a generator, which implements the iterator protocol:

注意function *语法和yield语句-这些表明这是一个生成器函数,而不是普通函数。 调用生成器函数时,您将返回一个生成器,该生成器实现了迭代器协议:

> var gen = naturalNumbers()
{}
> gen.next()
{ value: 0, done: false }
> gen.next()
{ value: 1, done: false }


It's also an iterable! You can verify this: if you call its iterator method, you get back the generator itself:

这也是一个迭代! 您可以验证这一点:如果调用其迭代器方法,则可以返回生成器本身:

> gen[Symbol.iterator]() === gen
true


But the more succient way to iterate over an iterable, of course, is via the for-of statement:

但是,当然,通过for-of语句迭代迭代的更简洁的方法是:

for (var n of naturalNumbers()){
  console.log(n)
}


Oops! Infinite loop (facepalm).

糟糕! 无限循环(facepalm)。

Generators are also cool because it is one solution (among several) to the callback hell problem. Notably, co and koa are frameworks which make heavy use of generators, and they both work in io.js out of the box. Read more for more in-depth treatments of generators.

生成器也很酷,因为它是回调地狱问题的一种解决方案(其中有几种)。 值得注意的是, cokoa是大量使用生成器的框架,它们都可以在io.js中直接使用。 阅读 更多内容,以更深入地了解发电机。

二进制和八进制数 (Binary and Octal Numbers)

Binary numbers are prefixed with 0b, and octal numbers are prefixed with 0O - that is, "zero" "O".

二进制数字以0b为前缀,八进制数字以0O为前缀-即“零”“ O”。

console.log(0b100)
console.log(0O100)


The above program outputs:

上面的程序输出:

4
64


承诺 (Promises)

The development of promises was very much a grassroots effort, starting out as libraries or components within various frameworks. Today, there are estabilished libraries like RSVP, Q, and Bluebird. Most of the major frameworks have promises built-in. There is a standard for promises called Promises A+ which most of the major implementations adhere to. To top it off, promises have been brought into the runtime itself! The story behind promises is quite inspiring.

诺言的发展很大程度上是基层的努力,始于各种框架中的库或组件。 如今,已经建立了像RSVPQBluebird这样的库。 大多数主要框架都有内置的承诺。 大多数主要实现都遵守一个称为Promises A +的承诺标准。 最重要的是,诺言已被带入运行时本身! 许诺背后的故事非常鼓舞人心。

Below is an example of how to turn a callback-based http client library into a function that returns a promise:

以下是如何将基于回调的http客户端库转换为返回诺言的函数的示例:

var request = require('superagent')

fetch('http://iojs.org')
  .then(function(reply){
    console.log('Returned ' + reply.text.length + ' bytes.')
  })

function fetch(url){
  return new Promise(function(resolve, reject){
    request(url).end(function(err, reply){
      if (err){
        reject(err)
      }else{
        resolve(reply)
      }
    })
  })
}


Promises can also be used effectively with generators - which is the strategy employed by co. Read this tutorial for a more in-depth explanation of promises.

Promise也可以有效地与生成器一起使用-这是co所采用的策略。 阅读本教程 ,以获得对Promise的更深入的解释。

新的字符串方法 (New String Methods)

Some new methods have been added to the native String object.

一些新方法已添加到本机String对象。

  • String.fromCodePoint(number) and .codePointAt(idx) are like String.fromCharCode and .charCodeAt(idx) except that they support unicode and therefore high code points translate into multi-byte characters

    String.fromCodePoint(number).codePointAt(idx)类似于String.fromCharCode.charCodeAt(idx)但它们支持Unicode,因此高代码点可转换为多字节字符

    > s = String.fromCodePoint(194564)
    '你'
    > s.codePointAt(0)
    194564
    
    
  • startsWith(s) and endsWith(s)

    startsWith(s)endsWith(s)

    > 'Hello, world!'.startsWith('Hello')
    true
    > 'Hello, world!'.endsWith('!')
    true
    
    
  • repeat(n)

    repeat(n)

    > 'foobar'.repeat(5)
    'foobarfoobarfoobarfoobarfoobar'
    
    
  • normalize() - returns the unicode normalization form of the string. To actually understand what that means, read about unicode equivalence.

    normalize() -返回字符串的Unicode规范化形式 。 要真正理解这意味着什么,请阅读unicode等效

符号 (Symbols)

The name symbol could be confusing because these symbols are not like the ones in Ruby or Smalltalk. Symbols in ES6 are used as hidden object properties. If you are a Pythonista: think double underscore magic methods.

名称symbol可能会造成混淆,因为这些符号与Ruby或Smalltalk中的符号不​​同。 ES6中的符号用作隐藏的对象属性。 如果您是Pythonista使用者,请考虑使用双下划线的魔术方法。

var secretMethod = Symbol('secret')
var obj = {}
obj[secretMethod] = function(){
  return 'foobar'
}
obj[secretMethod]() // returns `foobar`


Now, secretMethod won't show up within a for-in loop through the object's properties. In fact, no string property corresponds to the symbol referenced by secretMethod and there is no way to access the method without having a reference to the symbol. There are global "well-known" symbols in the system such as Symbol.iterator - which we've seen used to associate an object with its iterator. By all means, read more about symbols.

现在, secretMethod将不会显示在对象属性的for-in循环中。 实际上,没有字符串属性对应于secretMethod引用的符号,并且没有引用该符号就无法访问该方法的方法。 系统中存在全局的“知名”符号,例如Symbol.iterator我们已经看到了用于将对象与其迭代器关联的符号。 一定要阅读有关符号的更多信息。

模板字符串和多行字符串 (Template Strings and Multi-line Strings)

Template strings are borrowed from Ruby and Perl's string interpolation. It saves developers from having to awkwardly add together bits of strings - which often results in lots of quotes.

模板字符串是从Ruby和Perl的字符串插值中借用的。 它使开发人员不必笨拙地添加一些字符串,而这常常会导致大量引号。

> var name = 'Bobby'
undefined
> `Hello, ${name}!`
'Hello, Bobby!'


Note that template strings are enclosed by upticks "`" rather than single or double quotes - you'll have to reach up with your left pinky. What's exciting to me is that you can now write multi-line strings:

请注意,模板字符串用撇号“`”括起来,而不是用单引号或双引号引起来-您必须伸手可及的距离左小指。 让我兴奋的是,您现在可以编写多行字符串了:

var age = 5
var sql = `
select
  name
from
  people
where
  age > ${age};
`


Template strings have one more feature - to allow a custom function to evaluate the template in question. This is useful for situations which require specific parameter escaping - such as when sanitizing SQL parameters to prevent SQL injection attacks.

模板字符串还有一个功能-允许自定义函数评估相关模板。 这对于需要特定参数转义的情况很有用-例如在清理SQL参数以防止SQL注入攻击时。

var age = 5
var sql = sqlSanitize`
select
  name
from
  people
where
  age > ${age};
`


You can read more for in-depth treatments of template strings.

您可以阅读 更多内容以深入了解模板字符串。

标志后的显着特征 (Notable Features Behind Flags)

Some of the notable features still marked as in progress in io.js - version 1.0.3 at the time of this writing - are:

在io.js中,一些值得注意的功能( 撰写本文时为1.0.3版)仍标记为正在进行中:

总体印象 (Overall Impression)

I feel optimistic about the state of ES6 features on io.js. I like that all of these features work out of the box without any special flags. Mentally, this designation makes these features legit. For the most part, when these features are used the wrong way, the thrown error messages are helpful in guiding users. The features I am most excited about are generators and template strings. If I were starting a new hobby project today I would definitely give io.js a try, have a play, go wild, and try out these features in the wild.

我对io.js上ES6功能的状态感到乐观。 我喜欢所有这些功能都可以直接使用,没有任何特殊标志。 从精神上讲,这种指定使这些功能合法。 在大多数情况下,如果错误地使用这些功能,抛出的错误消息将有助于指导用户。 我最兴奋的功能是生成器和模板字符串。 如果今天我要开始一个新的爱好项目,那么我肯定会尝试io.js,试玩一下,试一试,然后在野外尝试这些功能。

翻译自: https://davidwalsh.name/es6-io

soket.io.js

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值