固有オブジェクトと非固有オブジェクトの継承の違い
4693 ワード
これは前編の固有のオブジェクトと非固有のオブジェクトのメンバー、値タイプの割り当て、非値型の参照の違いです.
の継続.
まず、固有のオブジェクトはブール値文字列の数値共通のオブジェクト配列関数です.
対応する対象はBoolean、String、Number、Object、Aray、Functです.(これらの文字はここで対象を指します.タイプ表現ではなく、これらの対象のタイプは全部function/関数です.)
前の編で話したのを覚えています.
値の種類に新しい可変メンバーを付与できませんでした.
ブール値文字列の値 値のタイプです.Boolean、String、Numberは値のタイプではなく、functionです.
この早口の言い方はすべて文字の書き方によるものです.私達は小文字でbootlean、string、number(実はjavascriptはつまりこのように表しています)または中国語のブール値を書いています.文字列、数値はタイプ、Boolean、String、NumberはJavaScriptの3つの対象を表しています.
だから:
/* */
Boolean.foo='foo';
String.foo='foo';
Number.foo='foo';
Object.foo='foo';
Array.foo='foo';
Function.foo='foo';
/* */
'string'.foo='foo';
(1).foo='foo';
true.foo='foo';
プロトタイプ(プロトタイプ定義)でオブジェクトの使用上の違いを拡張します.String.prototype.foo='foo';
var v=new String('string');
v.foo=3;
alert(v.foo);//3
var v='string';
v.foo=3;
alert(v.foo);//foo
あ、newというキーワードは使うか使わないかという違いがあります.同じ道理はBoolean、Numberにも適用されます.Object.prototype.foo='foo';
var v=new Object();
v.foo=3;
alert(v.foo);//3
var v={};
v.foo=3;
alert(v.foo);//3,
Object.prototype.foo={v:'foo'};//
var v={};
v.foo.v=3;
alert(v.foo.v);//3
var v={};
alert(v.foo.v);//3,
さらに:String.prototype.foo={v:'foo'};
var v=new String('string');
v.foo.v=3;
alert(v.foo.v);//3
var v='string';
alert(v.foo.v);//3,
値のオブジェクトと非値のオブジェクトは違います.ちょっと乱れているようです.私も適切な言語を見つけられませんでした.これを組織します.
var v=new String('string');//
var v='string';//
String.prototype.foo={foo:'foo'};// JavaScript string
しかし、固有ではないオブジェクト、つまりオブジェクトについてはそれほど複雑ではありません.
var foo=function(){};
foo.prototype={v:'foo',foo:{v:'foo'}};
var o=new foo;
o.v=3;
o.foo.v=4;
var o =new foo;
alert(o.v);//foo
alert(o.foo.v);//,
理由は簡単です.foo.prototypeは名前の特殊性だけで、JavaScriptにnew操作を特殊な継承処理をさせます.これ以外に、foo.prototypeも普通のオブジェクトの特性を持っています.値の種類に合ってコピーします.
それは迷いやすいo.foo.vのvも値のタイプじゃないですか?前のfooが無価値型であることを忘れないでください.
o.foo.v のfooはすでにfoo.prototype.fooを指しています.
もちろんo.foo.vとfoo.prototype.foo.vは同じ対象です.
同じことです
var o=new foo;
oはfooの一例で、二つのオブジェクトです.o!=foo;
o!=foo.prototype;
o.v!=foo.prototype.v;//
o.foo===foo.prototype.foo;//
値以外のタイプは同じメモリオブジェクトに参照されます.ただ、価値型の賦課ではなく、意味があります.変更するのは引用であり、単に値を変えるのではありません.
var foo=function(){};
foo.prototype={v:'foo',foo:{v:{v:'foo'}}};
var o=new foo;
o.v={};
o.foo.v={v:'new'};
var o =new foo;
alert(o.foo.v.v);//
今回も原型が改められました.var foo=function(){};
foo.prototype={v:'foo',foo:{v:{v:'foo'}}};
var o=new foo;
o.v={};
o.foo={v:'new'};
var o =new foo;
alert(o.foo.v.v);//
あとで変えたり変えたりしません.いったい問題はどこにありますか?違いはどこにありますか?違いは:
o.foo={v:'new'};
o.foo.v={v:'new'};
注意oは独立した実例の対象です.o.fooは引用です.foo.prototype.fooと同じ対象です.直接o.fooに対して賦課するのは当然です.引用を絞めて、新しいオブジェクトに引用しました.元のfoo.prototype.fooとは違っていますが、引用を断念しました.{v:'foo'}
相手でもありますが、o.foo.vのfooは範囲がはっきりしています.この範囲は同じ対象です.もちろん原型も変更されました.後で前のoを見てみます.ははは、もとはoは新しい実例で、範囲は違います.これを適用して範囲を確定する言い方です.
こんなに多いと言って、実はひと言だけで、引用の問題、先に範囲を決定するようにしましょう、異なっていますか?それとも同じですか?
標準的な言い方をすれば、これはSchope Chinの問題です.規範的な翻訳文を写してください.
http://www.cnblogs.com/winter-cn/archive/2008/07/07/1237168.html 書き記す
1.Scope Chinの次のオブジェクトを取得します.対象がなくなったら、5番目のステップに進みます.
2.結果(1)の[Has Property]メソッドを呼び出し、Identiferをパラメータとして渡す
3.結果(2)がtrueであれば、Reference(引用)タイプの値は、そのbase ojectが結果(1)です.
property nameはIdentiferです.
4.第1ステップにジャンプ
5.Referenceタイプを返します.そのbase ojectはnullです.そのproperty nameはIdentifeierです.
注:Reference(引用)タイプの値はJSエンジンが使用するデータタイプで、base objectとproperty nameの二つの部分に分けられます.JSコードにobj.propという表現があると仮定すると、Referenceタイプと解釈され、base objectは対象objであり、property nameは文字列「prop」である.
Scope Charinが開始されると、宿主オブジェクトとして設定されますので、グローバルコードの変数は宿主オブジェクトの属性です.Scope Chainは実行時にJSエンジンによって自動的にメンテナンスされ、コンパイル型エンジンも相応の運行時環境を作ってこのことをします.Scope Chainは、一般的に関数呼び出しまたはwithブロックに入るときに変更されます.
言うのは面倒くさいですが、使うのは簡単です.
もう一つのポイントはJavaScriptでこの言葉を継承するのは正確ではないです.祖先さえいつでも修正されます.これは継承です.明らかに転覆です.だから私はMixinを使うと思います.
混入はもっと適切で、どちらでもいいです.いずれにしてもJavaScriptで言っていることは全部同じです.