Mozilla があっちこっちで発表している JavaScript 2.0
http://developer.mozilla.org/presentations/xtech2006/javascript/
http://ajaxian.com/downloads/presentations/eich-ajax-experience-2006/
一つ一つ読んでみて、自分が使うと思う箇所だけ、ソースで書いてみた。(自分のリマインド用なのでメッチャ汚い)。
Type Annotation
JS1
var i; var element = document.getElementById('someInput'); i = parseInt(element.value); // 数値化
JS2
var i : int; // 型指定 var element = document.getElementById('someInput'); i : int = element.value; // 自動変換
JS1
Function.prototype.bind = function() { var __method = this, args = $A(arguments), object = args.shift(); return function() { return __method.apply(object, args.concat($A(arguments))); } };
JS2
Function.prototype.bind = function(object, ...args) { // アノテーションできる。 var __method = this; return function() { return __method.apply(object, args.concat(arguments)); // arguments は配列 } };
Class Extends
こんなことできたら最高!
JS2
var String = class extends String { // 無名クラス(クラスリテラル)は出来る?出来るよね? function gsub(pattern, replacement) { var result = '', source = this, match; replacement = arguments.callee.prepareReplacement(replacement); while (source.length > 0) { if (match = source.match(pattern)) { result += source.slice(0, match.index); result += (replacement(match) || '').toString(); source = source.slice(match.index + match[0].length); } else { result += source, source = ''; } } return result; } };
Package
これは普通に使いそうだな。
JS1
(function() { function OneClass() {} OneClass.prototype = {}; window['com.3zai.amachang.OneClass'] = OneClass; })(); var OneClass = window['com.3zai.amachang.OneClass']; var obj = new OneClass();
JS2
package com.3zai.amachang { class OneClass { } } import com.3zai.amachang.OneClass; // * でもいい var obj = new OneClass();
let
JS1
var i = 0; (function() { var i = 1; // こうしないと i が汚染される })(); alert(i);
JS2
var i =0; { let i = 1; // i が汚染されない } alert(i);
JS1
var elements = document.getElementsByTagName('li'); for(var i = 0; i < 10; i ++) { (function(i) { // 関数で囲まないとダメ。 elements[i].onclick = function() {alert(i)}; })(i); }
JS2
var elements = document.getElementsByTagName('li'); for(var i = 0; i < 10; i ++) { let(i = i){ elements[i].onclick = function() {alert(i)}; } }
JS1
var x = 1; var y = 2; var z = (function(x, y){ return x - y; })(y, x); // ここだけ x, y を逆転
JS2
var x = 1; var y = 2; var z = let (x = y, y = x) x - y; // ここだけ x, y を逆転
Group assignment
うほ!これ便利!
JS1
var elements = document.getElementsByTagName('div'); var div1 = elements[0]; var div2 = elements[1];
JS2
var [div1, div2] = document.getElementsByTagName('div');
var {0: div1, 1: div2, 'length': length} = document.getElementsByTagName('div');
JS1
var data = { '天野': { sex: '男', age: 24 }, '山下': { sex: '男', age: 24 } }; for(var name in data) { alert(name + 'は' + data[name].age + '才の' + data[name].sex + 'です。'); }
JS2
var data = { '天野': { sex: '男', age: 24 }, '山下': { sex: '男', age: 24 } }; for(let [name, {'sex': sex, 'age': age}] in data) { alert(name + 'は' + age + '才の' + sex + 'です。'); }
Iterators
これも!いいね!
JS2
function classNameIterator(element) { let it = Iterator(element.className.split(/\s+/)); for(let i in it) { if(i.length > 0) { yield i; } } }
Array Comprehensions
JS1
var array = [0, 1, 4, 5]; var result = []; for(var i = 0; i < array.length; i ++) { result.push(array[i] * array[i]); }
JS2
var array = [0, 1, 4, 5]; var result = [i * i for(i in Iterator(array))];
演算子オーバロード
JS2
class A { public static function +(a: Object, b:Object) { return a.a + b.b; } }
getter setter
JS2
var obj = {get x() {return 'えっくす'}}; alert(obj.x); // えっくす
Array Slice
おお!これも便利だ!
JS1
var elements = document.getElementsByTagName('div'); var div4 = elements[3]; var div5 = elements[4]; var div6 = elements[5];
JS2
var [div4, div5, div6] = document.getElementsByTagName('div')[3:5];
outer this bind
おお!これはちょっと・・・互換性が・・
JS1
(function() { var f = function() { alert(this); // こんにちわこんにちわ! }.bind(this); // バインドしないと this は使えない。 }).call('こんにちわこんにちわ!');
JS2
(function() { var f = function() { alert(this); // こんにちわこんにちわ! }; // バインドしなくても this を使える。 }).call('こんにちわこんにちわ!');
No more $A
arguments オブジェクトは配列のプロトタイプを持つようになった。