プライベートメソッドのサンプル

非標準の Function.prototype.caller を利用してプライベートメソッドを実現します。 Google Chrome 15, Firefox 7, Opera 11.50 で動作し、IE8- では動作しないことを確認しています。

HTML

<script src="https://raw.github.com/gist/816688/6b983e783f59b57c5293d2fd471be4f6f065c9d2/print.js"></script>
<h1>プライベートメソッドのサンプル</h1>

<h2>概要</h2>
<p>非標準の <code>Function.prototype.caller</code> を利用してプライベートメソッドを実現します。
Google Chrome 15, Firefox 7, Opera 11.50 で動作し、IE8- では動作しないことを確認しています。</p>

<h2>サンプル</h2>
<p>コンソール画面を開くと、"Call Error" が発生していることを確認できます。</p>

<div id="Print"></div>

<h2>参考リンク</h2>

<ul>
 <li><a href="https://developer.mozilla.org/Ja/Core_JavaScript_1.5_Reference/Global_Objects/Function#.E3.83.97.E3.83.AD.E3.83.91.E3.83.86.E3.82.A3_2">Function - MDN</a></li>
</ul>

CSS

html { margin: 0; padding: 0; }
body { margin: 0; padding: 1em; }
h1, h2, h3, h4, h5, h6 { font-weight: bold; color: #202020; }
h1 { margin: 1em 0; padding: 0; font-size: 150%; }
h2 { margin: 2.5em 0 1em; padding: 0; font-size: 120%; }
h3 { margin: 1em 0; padding: 0; font-size: 100%; color: #373; }
dl { margin: 1em 0; padding: 0; }
dt { margin: 1.5em 1em 1em; padding: 0; color: #337; font-weight: bold; }
dd { margin: 1em; padding: 0; }
pre { margin: 1.5em 2em; padding: 0.5em; font-family: monospace; font-size: 100%; font-weight: normal; }
code { font-family: monospace; font-size: 90%; font-weight: normal; }

/**
 * print.css
 *
 * @version 1.0
 * @author think49
 */

#Print { margin: 1em 0; padding: 0.5em; border: 1px solid #999; color: black; background-color: #EFEFEF; font-family: monospace; }

JavaScript

/**
 * private-method.js
 *
 * @version 1.0
 * @author think49
 * @see <a href="https://developer.mozilla.org/Ja/Core_JavaScript_1.5_Reference/Global_Objects/Function#.E3.83.97.E3.83.AD.E3.83.91.E3.83.86.E3.82.A3_2">Function - MDN</a>
 */

function isInstanceMethod (fn, thisArg) {
  var prop;

  for (prop in thisArg) {
    if (this[prop] === fn) {
      return true;
    }
  }

  return false;
}


/**
 * @constructor
 */
function Hello (value) { this.value = value; }

Hello.prototype = {
  /**
   * @private
   */
  _console: function (string) {
    var prop;

    if (!(this instanceof Hello) || isInstanceMethod(this._console.caller, this)) {
      throw new Error('Call Error');
    }

    print('Hello, ' + string);
  },

  /**
   * @public
   */
  output: function () {
    this._console(this.value);
  }
};

// プライベートメソッドを呼び出せる
new Hello('World!').output();


// プライベートメソッドを呼び出せない
Hello.prototype.output('World!');
Hello.prototype._console('World!');