Hatena::ブログ(Diary)

hogehoge @teramako RSSフィード

 

2014-07-04

Symbolの使い道 - 他に迷惑を掛けないプロトタイプ拡張

先日 Firefox Nightly で Symbol が実装されたわけだが、その使い道を考えていた。それで思いつたのが、Symbolを使えば迷惑を掛けずにプロトタイプ拡張ができるのでは、ということ。

こんな感じ。

"use strict";
{
  let keys =    Symbol.for("teramako.Object.keys"),
      values =  Symbol.for("teramako.Object.values"),
      entries = Symbol.for("teramako.Object.entries");

  Object.prototype[keys] = function* () {
    yield * Object.keys(this);
  };
  Object.prototype[values] = function* () {
    for (var key of this[keys]())
      yield this[key];
  };
  Object.prototype[entries] = function* () {
    for (var key of this[keys]())
      yield [key, this[key]];
  };
}
  • プロパティキーは文字列ではなく、シンボルなので、Object.keys,Object.getOwnPropertyNames,for-in で出てくることはない。
  • 他所からも呼び出せるようにSymbol.for()でSymbolをつくる
    • 名前が被らるのは嫌なので"名前空間.シンボル名"みたいに名前空間を付けておく

他コンテキストのブロックからも以下の様な感じで呼び出せる。

let entries = Symbol.for("teramako.Object.entries")
for (var [k, v] of obj[entries]()) {
  console.log(k + ": " + v);
  ...;
}

この完全にプライベートというわけでもなく、かと言ってパブリックな感じでもない微妙な感じが堪らなく良く思えるのだが、どうだろう?

2014-06-25

Firefox 33でES6のSymbolが実装された

不完全ながら ES6 の Symbol が実装された。

Symbolは、Undefined, Null, Boolean, Number, String に続く新たなプリミティブな型である。

既にChromeのV8エンジンには実装されていて、Symbolについて - JS.nextにて記事になっているので、どんなものかは、こちらを参照すると良いと思う。

ただ、一点、V8も含め、Object.getOwnPropertySymbols() が実装されていて、完全にプライベートなプロパティを作れるわけではないことには注意。

var obj = (function(){
  var o = {};
  var sym = Symbol();
  o[sym] = "foo";
  return o;
}());

obj[Object.getOwnPropertySymbols(obj)[0]]; // === "foo";

2014-06-12

Firefox 33 で ES6 の TemplateLiteral の一部が実装された

ついにきた。

JavaScript にはヒアドキュメントがない」などと言われてきた。そんなディスりとはおさらばだ。

JavaScriptの文字列リテラル"'でくくることだった。が、これらで複数行を実現するには少々面倒であった。

しかし、今回の実装でもう一つ、`(バッククォート)でくくるという表現ができるようになった。

var str = `a
b
c
d`;

と書けるようになる。

TemplateLiteralには他にも機能があるのだが、今回の実装はここまで。

最終的には、以下の様に、${}内に式を埋め込めたり、関数`...` という記述で関数に値を渡すことができるようになるはず。

var obj = {
  tag: "p",
  class: "fooClass"
};
html`<${obj.tag} class="${obj.class}">hoge
foo
bar</${obj.tag}>`
// <p class="fooClass">hoge
// foo
// bar</p>

追記(2014-06-25)

${expr}による、式の埋め込みが実装された。