JavaScript constructorとinstanceof,JSOOのカップル

4708 ワード

少なくともJavaScriptOOを試みるプログラマーは、ビジネスそのものではなくオブジェクト向けメカニズムのシミュレーションに多くの労力を費やす.
これはJava,C++さらにPhpの開発者にとって想像しがたいことだ.
さらに悪いことに、シミュレーションOOはJavaScriptの高級プログラマーに邪悪な魅力を持っている.
この仕事をするのは業務の上で超然としているので、新しいプログラミング言語を創造するような快感があり、IQを思う存分振り回すことができます.
先年、皆さんが自分のサイトのcommon.jsをフレームワークにしたいと思っていたように、YUI、JQueryなどの強気な発売までは少し落ち着きました.
しかし、各フレームワークではJavaScriptOOのシミュレーションが行われているが、誰がバケツ1杯の糊を作ることができるかはまだ来ていないだろう.
もしかすると江湖は必要としない覇者が現れて、あるいはみんなはJS 2.0+を待つだけでいいです.
newがオブジェクト向けだとすれば、JavaScriptはこの点で非常に良いことは明らかだ.
 
  
function Person(name){
this.name = name;
}
var lenel = new person("lenel");
alert(lenel.constructor === Person);
alert(lenel instanceof Person === true);
alert(lenel instanceof Object === true);

ここまで、すべてが調和している.
オブジェクトのconstructorは文字通りそのPersonを構築することを指す.
オブジェクトはそのPersonを構築する一例である.
すべてのオブジェクトはObjectのインスタンスで、Javaに似ています.
JavaScriptは、メソッドの拡張と継承を実現するためにプロトタイプを提供します.
 
  
Person.prototype.getName = function(){
return this.name
};

このように定義後、すべてのオブジェクトにgetNameを持たせる方法がある.
もちろんオブジェクト構造に書く場合も
 
  
function Person(name){
this.name = name;
this.getName = function(){
return this.name;
};
}

しかし、このようなやり方は、追加の性能損失をもたらすという欠点だけでなく、プライベート変数にアクセスできる特権ももたらす.
prototypeを使う書き方とは他にも違いがありますが、これは本稿のポイントではありません.
次に、継承を考えてみましょう.よくある書き方はこうです.
 
  
function Stuff(name,id){
this.name = name;
this.id = id;
}
Stuff.prototype = new Person();
var piupiu = new Stuff("piupiu","007");
alert(piupiu.getName());

とても良くて、getNameの方法を継承しました;
考察の下でinstanceof
 
  
alert(piupiu instanceof Stuff === true);
alert(piupiu instanceof Person === true);

とても良くて、StuffとPersonが関係があることを説明しました.piupiuはその2つの例で、とてもJavaです.
次にconstructorについて考察します
 
  
alert(piupiu.constructor === Stuff);//false
test(piupiu.constructor === Person);//true

問題はnewのStuffがなぜconstructorなのかPersonなのに、
ここで理屈をこねるのも無理だから,われわれは結論を覚えるしかない.
結論:オブジェクトのconstructorプロパティは、そのコンストラクタではなく、そのコンストラクタのprototypeプロパティを指すconstructorプロパティです.
文字の基礎があまりにも悪いので,自分で読んでもはっきり言えなかったと思った.
ここに置く:
オブジェクトpiupiuのconstructorプロパティは、そのコンストラクタStuffのprototypeプロパティのconstructorプロパティを指します.
Stuff.prototype=new Person();
だからStuff.prototype.constructor==Person.
だからpiupiu.consturctor==Person.
以上の結論は,オブジェクトが継承されたときだけでなく,オブジェクトを定義するときにも現れる.
 
  
function Student(name){
this.name = name;
}
Student.prototype = {
getName:function(){
return this.name;
},
setName:function(name){
this.name = name;
}
}

方法が多ければ、よくこのように書いて、規則的に見えます.
実はこの書き方はconstructorを犠牲にしたのです
 
  
var moen = new Student("moen");
alert(moen.constructor === Student);//false
alert(moen.constructor === Object);//true

{}がnew Object()に相当するため、上記の結論によりprototype={}となるとconstructorが変わる.
コンストラクトを守れ!継承時に親のメソッドcopytoサブクラスをループで
 
  
function Stuff1(name,id){
this.name = name;
this.id = id;
}
for(var fn in Person.prototype){
Stuff1.prototype[fn] = Person.prototype[fn];
}
var piupiu1 = new Stuff1("piupiu1","008");
alert(piupiu1.getName() === "piupiu1");
alert(piupiu1.constructor === Stuff1);

It works!私たちが喜んで父の方法を継承したとき、私たちは親子関係を失った.
 
  
alert(piupiu1 instanceof Stuff1 === true);//true
alert(piupiu1 instanceof Person === true);//false

明らかに、Stuff 1はPersonに受け継がれているとは言っていません.forループだけが何を説明することができますか.
これは矛盾のペアのようです..これによって必ず彼を失います.
だから、オブジェクトを深く使うとき、うっかりすると、instantceofとconstructorに字面の意味を失わせます.
だから、フレームワークを使う时、継承机能を提供したら、あなたが継承のためにどれを放弃したか分からない.
だから、OOをシミュレートするときは、この2つの字面の意味に代わる属性や方法の実装を提供しなければなりません.そして、使用者に知らせなければなりません.
シミュレーションOOは決してこの問題だけではなく、サブクラスメソッドで親の同名メソッドを呼び出します.このOO言語でよく見られる特性は、
JavaScriptの実現も非常に困難で、マスターたちは基本的にそれぞれのセットを持っていますが、ベースライブラリのように、心を込めて使ったほうが自然です.
もちろんinstanceofとconstructorの使用を捨てることができて、このような事があることを知らないと思って、仕事は依然として続けることができて、死ぬことができません.
しかし、もしあなたが単独で戦っていないなら、パートナーにこの友达を捨てることを知らせましょう.
今日のようなことは、鳥たちはよく知っていますが、チームの中で誰もが統一的な認識を持っていなければ、それは隠れた危険です.
1つの面白い现象<>はinstanceofを强调して、<>はconstructorを强调します.それぞれ别の1つのペンに対して持って行ったことがありますかます一言も言いません.恨み...