<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>仮ぶろぐ &#187; property</title>
	<atom:link href="http://plusb.jp/blog/?feed=rss2&#038;tag=property" rel="self" type="application/rss+xml" />
	<link>http://plusb.jp/blog</link>
	<description>今更なことをそれでもつらづらと書くブログ</description>
	<lastBuildDate>Tue, 07 May 2013 09:06:48 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>メンバー変数ではなくてプロパティーについて</title>
		<link>http://plusb.jp/blog/?p=115</link>
		<comments>http://plusb.jp/blog/?p=115#comments</comments>
		<pubDate>Tue, 02 Feb 2010 00:40:41 +0000</pubDate>
		<dc:creator>M. K.</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[property]]></category>

		<guid isPermaLink="false">http://plusb.jp/blog/?p=115</guid>
		<description><![CDATA[JavaScriptにはpublicやprivate等の概念は無いですがやはり、private相当の属性にはgetterやsetterを提供してやりたくなります。 余談ですが、プラべーメンバーの隠蔽はコンストラクター内で &#8230; <a href="http://plusb.jp/blog/?p=115">続きを読む <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>
JavaScriptには<code>public</code>や<code>private</code>等の概念は無いですがやはり、<code>private</code>相当の属性にはgetterやsetterを提供してやりたくなります。<br />
<span id="more-115"></span><br />
余談ですが、プラべーメンバーの隠蔽はコンストラクター内でクロージャーを使用すれば実現可能ですが他のメンバー関数からも<br />
直接参照出来なくなるので好みではありません(命名規則などのルールで拘束すれば十分だと思ってます）。
</p>
<p>
で、getterやsetterの実装を考えると高級言語によくあるpropertyは良くできた仕様です。<br />
内部的にsetterを定義しないか<code>readonly</code>を宣言すれば参照のみ出来るメンバー変数のできあがりです。
</p>
<pre>
[C#]
{
 private int foo_;
 property int foo {
     get { return foo_; }
 };
</pre>
<p>getter,setterの実装をどうするか考えた結果、採用(別に私のオリジナルではありません）したのが以下の方法です。</p>
<pre>
Class = function() { this._foo = 0; } <span style="#1111EE">//privateメンバーは'_'で始める</span>
Class.prototype.foo = function (value) {
    if(!arguments.length) {
        return this._foo;
    } else {
        this._foo = value;
    }
}
</pre>
<p>
実用上これで問題ないですが、.Net Framework のPropertyGridやXmlSerializerを実装しようとすると機械的にgetter,setterの<br />
有無を確認できる方が都合が良いです。かといって getFoo() 等にするのは嫌・・・。
</p>
<p>
で、あいだととってgetter,setterをプライベート相当で定義することにします。</p>
<pre>
Class.prototype.__foo = {}
Class.prototype.__foo.get = function() {
   return this._foo;
}
Class.prototype.foo = function (value) {
    if(!arguments.length) {
        return this.__foo.get();
    } else {
        this.__foo.set(value);  <span style="#1111EE">//エラー処理は割愛</span>
    }
}
</pre>
<p>
まあ、これを一つ一つ書くのは面倒なので関数を用意します。</p>
<pre>
function __property__(object, name, get, set, def) {
    var _nm = "_" + name;
    var __nm = "__" + name;
    object.prototype[_nm] = def || false;
    object.prototype[__nm] = { 'get': get, 'set': set };
    return function (value) {
        if (!arguments.length) {
            !this[__nm].get &#038;&#038; throw new Error('has not getter');
            return this[__nm].get.apply(this);
        } else {
            !this[__nm].set &#038;&#038; throw new Error('has not setter');
            this[__nm].set.apply(this, arguments);
        }
    };
}
Class.prototype.foo = __property__(
    Class,
    "foo", 
    function() { return this._foo; }, 
    null , 
    "hoge");
</pre>
<div style="font-size: 120%;">
・・・やり過ぎかなorz
</div>
]]></content:encoded>
			<wfw:commentRss>http://plusb.jp/blog/?feed=rss2&#038;p=115</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
