Nick Justice は、GitHub 開発者プログラムのメンバーです。 ES6 言語標準がリリースされるずっと前に、彼は Babel などのトランスパイラーとブラウザの最新バージョンを使用して、プロジェクトで ES6 機能を使用していました。彼は、ES6 の新機能が JavaScript の記述方法を大きく変えるだろうと信じています。
ES6 (ECMAScript 6) は、JavaScript 言語の今後の新バージョンの標準であり、コードネームは Harmony (ハーモニーを意味します。明らかに我が国のペースに追いついておらず、チャイニーズ ドリーム バージョンに入りました) と名付けられています。最後に規格が策定されたのは、2009 年にリリースされた ES5 です。 ES6 の標準化作業は現在進行中であり、正式に最終版がリリースされるのは 2014 年 12 月の予定です。ただし、ほとんどの標準はすでに整備されており、ES6 のブラウザ サポートが実装されています。
テクノロジーの発展は急速に進んでいますが、私たちが学びを止めなければ、新しいテクノロジーによって淘汰されることはありません。一緒に es6 の新機能を学びましょう。
矢印演算子
C# または Java を知っている場合は、ES6 の新しい矢印演算子 => も同じ目的を持っている必要があります。関数の記述が簡素化されます。演算子の左側は入力パラメータで、右側は実行される操作と戻り値Inputs=>outputsです。
JS ではコールバックが一般的であることはわかっていますが、通常、コールバックは匿名関数の形式で表示されます。毎回関数を記述する必要があり、非常に面倒です。アロー演算子を導入すると、コールバックを簡単に作成できます。以下の例を参照してください:
var array = [1,2,3]; // 传统写法写法 array.forEach(function(v) { console.log(v); }); // ES6写法 array.forEach(v => console.log(v));
クラスサポート
ES6 ではクラスのサポートが追加され、class キーワードが導入されました (実際、class は常に JavaScript の予約語でした。その目的は、将来新しいバージョンで使用される可能性を考慮することであり、今回、ついに追加されました)便利です)。 JS 自体はオブジェクト指向であり、ES6 で提供されるクラスは実際には JS プロトタイプ パターンのラッパーにすぎません。ネイティブ クラスのサポートが提供されるようになったことで、オブジェクトの作成と継承がより直感的になり、親クラスのメソッドの呼び出し、インスタンス化、静的メソッド、コンストラクターなどの概念がより視覚的になりました。
次のコードは、ES6 でのクラスの使用を示しています。
// 类的定义 class Animal { // ES6中新型构造器 constructor(name) { this.name = name; } // 实例方法 sayName() { console.log('My name is ' + this.name); } } // 类的继承 class Programmer extends Animal { constructor(name) { // 直接调用父类构造器进行初始化 super(name); } program() { console.log("I'm coding..."); } } // 测试我们的类 var animal = new Animal('dummy'), wayou = new Programmer('wayou'); animal.sayName(); // 输出 'My name is dummy' wayou.sayName(); // 输出 'My name is wayou' wayou.program(); // 输出 'I'm coding...'
拡張オブジェクト リテラル
オブジェクト リテラルが強化され、記述方法がより簡潔かつ柔軟になり、オブジェクトを定義するときに実行できることが増えました。具体的には、
に示されています。1. プロトタイプはオブジェクト リテラルで定義できます
2. 関数キーワード
を使用せずにメソッドを定義できます。
3. 親クラスのメソッドを直接呼び出します
このように、オブジェクト リテラルは上記のクラスの概念とより一貫性があり、オブジェクト指向 JavaScript の記述がより簡単かつ便利になります。
// 通过对象字面量创建对象 var human = { breathe() { console.log('breathing...'); } }; var worker = { __proto__: human, // 设置此对象的原型为human, 相当于继承human company: 'freelancer', work() { console.log('working...'); } }; human.breathe(); // 输出 'breathing...' // 调用继承来的breathe方法 worker.breathe(); // 输出 'breathing...'
文字列テンプレート
文字列テンプレートは比較的シンプルで理解しやすいです。 ES6 では、バックティック ` を使用して文字列を作成できます。このメソッドで作成された文字列には、ドル記号と中括弧で囲まれた変数 ${vraible} を含めることができます。 C# などのバックエンドの厳密に型指定された言語を使用したことがある場合は、この機能に精通しているはずです。
// 产生一个随机数 var num = Math.random(); // 将这个数字输出到console console.log(`your num is ${num}`);
解体
配列またはオブジェクト内の値を自動的に解析します。たとえば、関数が複数の値を返したい場合、従来のアプローチでは、オブジェクトを返し、各値をオブジェクトのプロパティとして返します。しかし、ES6 では、構造化の機能を使用して、配列を直接返すことができ、配列内の値は値を受け取る対応する変数に自動的に解析されます。
function getVal() { return[1,2]; } var [x,y] = getVal(), // 函数返回值的解构 console.log('x:' + x + ', y:' + y); // 输出:x:1, y:2 [name,,age] = ['wayou','male','secrect']; // 数组解构 console.log('name:' + name + ', age:' + age); //输出:name:wayou, age:secrect
パラメータのデフォルト値、可変パラメータ、拡張パラメータ
デフォルトのパラメータ値
関数を定義するときに、以前のように目的を達成するために論理 OR 演算子を使用する代わりに、パラメーターのデフォルト値を指定できるようになりました。
function sayHello(name) { // 传统的指定默认参数的方式 var name = name || 'dude'; console.log('Hello ' + name); } sayHello(); // 输出:Hello dude sayHello('Wayou'); // 输出:Hello Wayou // 运用ES6的默认参数 function sayHello2(name = 'dude') { console.log(`Hello${name}`); } sayHello2(); // 输出:Hello dude sayHello2('Wayou'); // 输出:Hello Wayou
不定パラメータ
無期限パラメータとは、無期限の数の名前なしパラメータを受け取る際に、関数内で名前付きパラメータを使用することです。これは単なる糖衣構文であり、以前の JavaScript コードでは、引数変数を通じてこれを実現できました。変数パラメータの形式は、3 つのピリオドの後にすべての変数パラメータを表す変数名が続きます。
たとえば、次の例では、...x は add 関数に渡されるすべてのパラメータを表します。
// 将所有参数相加的函数 function add(...x) { return x.reduce((m,n) => m+n); } // 传递任意个数的参数 console.log(add(1,2,3)); // 输出:6 console.log(add(1,2,3,4,5)); // 输出:15
拡張パラメータ
拡張パラメータは構文糖衣の別の形式であり、apply を経由せずに配列または配列のようなパラメータを関数パラメータとして直接渡すことができます。
var people = ['Wayou','John','Sherlock']; // sayHello函数本来接收三个单独的参数人一,人二和人三 function sayHello(people1, people2, people3) { console.log(`Hello${people1}, ${people2}, ${people3}`); } // 但是我们将一个数组以拓展参数的形式传递,它能很好地映射到每个单独的参数 sayHello(...people); // 输出:Hello Wayou,John,Sherlock // 而在以前,如果需要传递数组当参数,我们需要使用函数的apply方法 sayHello.apply(null, people); // 输出:Hello Wayou,John,Sherlock
let キーワードと const キーワード
let は var と考えることができますが、定義される変数は特定のスコープ内でのみ使用でき、このスコープの外では無効になる点が異なります。 const は非常に直感的で、定数、つまり値を変更できない変数を定義するために使用されます。
for (let i=0; i<2; i++) { console.log(i); // 输出: 0,1 } console.log(i); // 输出:undefined,严格模式下会报错
for of 值遍历
我们都知道for in循环用于遍历数组,类数组或对象,ES6中新引入的for of循环功能相似,不同的是每次循环它提供的不是序号而是值。
var someArray = ["a","b","c"]; for (v of someArray) { console.log(v); // 输出 a,b,c }
iterator, generator
1.iterator: 它是这么一个对象,拥有一个next方法,这个方法返回一个对象{done,value},这个对象包含两个属性,一个布尔类型的done和包含任意值的value
2.iterable: 这是这么一个对象,拥有一个obj[@@iterator]方法,这个方法返回一个iterator
3.generator: 它是一种特殊的iterator。反的next方法可以接收一个参数并且返回值取决与它的构造函数(generator function)。generator同时拥有一个throw方法
4.generator函数: 即generator的构造函数。此函数内可以使用yield关键字。在yield出现的地方可以通过generator的next或throw方法向外界传递值。generator 函数是通过function*来声明的
5.yield关键字:它可以暂停函数的执行,随后可以再进进入函数继续执行
模块
在ES6标准中,JavaScript原生支持module了。这种将JS代码分割成不同功能的小块进行模块化的概念是在一些三方规范中流行起来的,比如CommonJS和AMD模式。
将不同功能的代码分别写在不同文件中,各模块只需导出公共接口部分,然后通过模块的导入的方式可以在其他地方使用。
// point.js module "point" { export class Point { constructor(x,y) { public x=x; public y=y; } } } // myapp.js // 声明引用的模块 module point from "/point.js"; // 这里可以看出,尽管声明了引用的模块,还是可以通过指定需要的部分进行导入 import Point from "point"; var origin = new Point(0,0); console.log(origin); Map,Set 和 WeakMap,WeakSet
这些是新加的集合类型,提供了更加方便的获取属性值的方法,不用像以前一样用hasOwnProperty来检查某个属性是属于原型链上的呢还是当前对象的。同时,在进行属性值添加与获取时有专门的get,set方法。
// Sets var s = new Set(); s.add("hello").add("goodbye"); s.size === 2; s.has("hello") === true; // Maps var m = new Map(); m.set("hello", 42); m.set(s, 34); m.get(s) == 34; 有时候我们会把对象作为一个对象的键用来存放属性值,普通集合类型比如简单对象会阻止垃圾回收器对这些作为属性键存在的对象的回收,有造成内存泄漏的危险。而WeakMap,WeakSet则更加安全些,这些作为属性键的对象如果没有别的变量在引用它们,则会被回收释放掉,具体还看下面的例子: // Weak Maps var wm = new WeakMap(); wm.set(s, {extra: 42}); wm.size === undefined // 对象释放了 // Weak Sets var ws = new WeakSet(); ws.add({data: 42}); // 因为添加到ws的这个临时对象没有其他变量引用它,所以ws不会保存它的值,也就是说这次添加其实没有意思 Proxies Proxy可以监听对象身上发生了什么事情,并在这些事情发生后执行一些相应的操作。一下子让我们对一个对象有了很强的追踪能力,同时在数据绑定方面也很有用处。 // 定义被侦听的目标对象 var engineer = {name: 'Joe Sixpack', salary: 50}; // 定义处理程序 var interceptor = {set: function(receiver, property, value) { console.log(property, 'is changed to', value); receiver[property] = value; } }; // 创建代理以进行侦听 engineer = Proxy(engineer, interceptor); //做一些改动来触发代理 engineer.salary = 60; // 控制台输出:salary is changed to 60
上面代码我已加了注释,这里进一步解释。对于处理程序,是在被侦听的对象身上发生了相应事件之后,处理程序里面的方法就会被调用,上面例子中我们设置了set的处理函数,表明,如果我们侦听的对象的属性被更改,也就是被set了,那这个处理程序就会被调用,同时通过参数能够得知是哪个属性被更改,更改为了什么值。
Symbols
我们知道对象其实是键值对的集合,而键通常来说是字符串。而现在除了字符串外,我们还可以用symbol这种值来做为对象的键。Symbol是一种 基本类型,像数字,字符串还有布尔一样,它不是一个对象。Symbol 通过调用symbol函数产生,它接收一个可选的名字参数,该函数返回的symbol是唯一的。之后就可以用这个返回值做为对象的键了。Symbol还可以用来创建私有属性,外部无法直接访问由symbol做为键的属性值。
(function() { // 创建 symbol var key = Symbol("key"); function MyClass(privateData) { this[key] = privateData; } MyClass.prototype = { doStuff: function() { ...this[key]... } }; })(); var c = new MyClass("hello"); c["key"] === undefined //无法访问该属性,因为是私有的 Math,Number,String,Object 的新API 对Math,Number,String还有Object等添加了许多新的API。 // Number // 不同的两个Number之间的最小的差 Number.EPSILON // 判断是否是整数 Number.isInteger(Infinity) // false // 判断是否为非数字 Number.isNaN("NaN") // false // Math Math.acosh(3) // 1.762747174039086 Math.hypot(3,4) // 5 Math.imul(Math.pow(2,32)-1, Math.pow(2,32)-2) // 2 // String "abcde".contains("cd") // true "abc".repeat(3) // "abcabcabc" // Array // 将一个类数组对象或可迭代对象转换成真实的数组 Array.from(document.querySelectorAll('*')) // 将它的任意类型的多个参数放在一个数组里并返回 Array.of(1,2,3) // 将一个数组中指定区间的所有元素的值, 都替换成或者说填充成为某个固定的值 [0,0,0].fill(7,1) // [0,7,7] // 用来查找数组中某指定元素的索引, 如果找不到指定的元素, 则返回 -1 [1,2,3].findIndex(x => x == 2) // 1 // 返回一个 Array Iterator 对象,该对象包含数组中每一个索引的键值对 ["a","b","c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"] // 返回一个数组索引的迭代器 ["a","b","c"].keys() // iterator 0, 1, 2 // 返回一个新的 Array Iterator 对象,该对象包含数组每个索引的值 ["a","b","c"].values() // iterator "a", "b", "c" // Object Object.assign(Point, {origin: new Point(0,0)}) Promises Promises是处理异步操作的一种模式,之前在很多三方库中有实现,比如jQuery的deferred 对象。当你发起一个异步请求,并绑定了.when(), .done()等事件处理程序时,其实就是在应用promise模式。 // 创建 promise var promise = new Promise(function(resolve,reject) { // 进行一些异步或耗时操作 if(/*如果成功 */) { resolve("Stuff worked!"); } else { reject(Error("It broke")); } }); // 绑定处理程序 promise.then(function(result) { // promise成功的话会执行这里 console.log(result); // "Stuff worked!" }, function(err) { // promise失败会执行这里 console.log(err); // Error: "It broke" });
有关ES6的新特性就给大家介绍这么多,希望对大家有所帮助!