IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

mozillaのjavascript2.0を書いてみた(自分用)

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 オブジェクトは配列のプロトタイプを持つようになった。