js構造関数プロトタイプ問題分析(一部のボロボロコードによるブログ)
3807 ワード
Email:longsu 2010 at yeah dot net
昔、ある人が下記のコードを送ってくれました.何か問題がありますか?今日はもう古い話をします.いっそブログを書いて皆さんにシェアします.事前に声明しましたが、本博は問題を分析するだけで、解決策を提供していません.
コードはどう見ても頭が痛いです.よく見たらもっと頭が痛いです.どうせコードはこう書きません.コードは以下の通りです
まとめ:構造関数のプロトタイプを変えるタイミングが重要で、動態的にプロトタイプを変えるには慎重で、特にいくつかのインスタンスを作成してからです.作成したオブジェクトは新しい原型オブジェクトを使用しません.
もう少し話して、次のような面白い実験をします.コードをよく読んでください.
1、すべてのjsオブジェクトのプロトタイプチェーンの最後は同じオブジェクト、すなわちObjectのプロトタイプ属性であり、これはなぜ--00--を出力するのですか?
2、コンストラクタデフォルトのprototypeはObjectの一例で、この関数が作成したインスタンスはすべて同じオブジェクトを共有します.
3、Objectのprototype機能を修正するのは強大で、結果が深刻で、慎重です.
4、global-00を出力したのは変数を検索する時、windowのプロトタイプチェーンでxxxを見つけたからです.詳細はjs変数検索規則を研究してください.
5、各関数にはprototype属性があり、関数も対象であるため、プロトタイプチェーンもあります.関数をオブジェクトとして使用すると、プロトタイプチェーン上で属性検索が行われ、関数を構成関数として使用すると新しいオブジェクトが作成され、プロトタイプとして関数のプロトタイプが使用されます.
6、以上の実験はchrome 25バージョンを使って、IEブラウザには一定の出入りがあります.特に可愛いIE 6、7、8.良いニュースはwin xpが歴史の舞台から退出するので、IE 6、7、8もいっしょに歩くべきでしょう.
longsu 2010 at yeah dot net私のメールボックスで、用事があったらメールしないでください.
原型についてはまだたくさんの内容がありますが、本文とはそんなに関係がないので、もう書くことができません.
昔、ある人が下記のコードを送ってくれました.何か問題がありますか?今日はもう古い話をします.いっそブログを書いて皆さんにシェアします.事前に声明しましたが、本博は問題を分析するだけで、解決策を提供していません.
コードはどう見ても頭が痛いです.よく見たらもっと頭が痛いです.どうせコードはこう書きません.コードは以下の通りです
function aaa(sColor){
this.color = sColor;
if(typeof aaa._is_ == "undefined"){
aaa.prototype.sayColor = function(){
alert(this.color);
};
}
aaa._is_ = true;
}
function bbb(sColor,name){
this.name = name;
if(typeof bbb._iss_ == "undefined"){
bbb.prototype = new aaa();
bbb.prototype.sayName = function(){
alert(this.name);
};
}
bbb._iss_ = true;
}
コードを見た後、これは二つのコンストラクションです.まず最初に、この関数を使用して最初のインスタンスを作成したり、関数を直接呼び出したり(グローバルオブジェクトを汚染する)すると、そのプロトタイプに操作色の属性を追加する方法があります.コードの正確性は大丈夫です.次のコードでテストします.var a1 = new aaa("red");
var a2 = new aaa("green");
console.dir(a1);
console.dir(a2);
console.log(a1.__proto__ === a2.__proto__); // true
は、現在、第二のコンストラクターについて話しています.この関数を使って第一のインスタンスを作成するか、あるいは関数(全体のオブジェクトを汚染する)を直接呼び出したときに、この関数のプロトタイプを値を再割り当てし、新しいプロトタイプに操作属性を追加する方法は、継承するという意味があります.しかし問題が来ました.最初のインスタンスを作成してif文を実行した時にのみプロトタイプを変更し始めました.もう間に合わないです.最初のインスタンスはデフォルトのプロトタイプになります.テストコードは以下の通りです.var bbb_proto = bbb.prototype; // bbb
var b1 = new bbb("red", "liuchen1");
var b2 = new bbb("green", "liuchen2");
console.dir(b1);
console.dir(b2);
console.log(b1.__proto__ === b2.__proto__); // false
bbb.prototype = bbb_proto;
var b3 = new bbb("green", "liuchen3");
console.log(b1.__proto__ === b3.__proto__); // true
ここまで書いて問題を分析しました.まとめてみます.まとめ:構造関数のプロトタイプを変えるタイミングが重要で、動態的にプロトタイプを変えるには慎重で、特にいくつかのインスタンスを作成してからです.作成したオブジェクトは新しい原型オブジェクトを使用しません.
もう少し話して、次のような面白い実験をします.コードをよく読んでください.
function a(){}
function b(){}
// Object.prototype.xxx = '--00--'; // IE
new a().__proto__.__proto__.xxx = "--00--"; // IE
console.log(new a().__proto__ === new b().__proto__); //false // IE true, undefined === undefined
console.log(new a().__proto__.__proto__ === new b().__proto__.__proto__); //true // IE ,
console.log(Object.prototype === new a().__proto__.__proto__); //true // IE ,
console.log(a.prototype instanceof Object); //true
console.log(new a().__proto__ instanceof Object); //true // IE
console.log(new a() instanceof Object) //true
console.log(Object.prototype instanceof Object) //false
console.log(a.prototype === b.prototype); //false
console.log(new a().__proto__ === a.prototype); //true
console.log(typeof(a.prototype)); //object
console.log(typeof(Object.prototype)); //object
console.log(new a().xxx); //--00--
console.log(new b().xxx); //--00--
console.log(Object.xxx); //--00--
console.log(new Object().xxx); //--00--
console.log(window.xxx); //--00--
console.log(document.xxx); //--00--
console.log(document.head.xxx); //--00--
console.log(document.getElementById("div").xxx); //--00-- // dom
console.log("global", xxx); //global --00--
yyy = "0000";
delete window.yyy;
console.log(window.yyy); //undefined
にめちゃくちゃなコードが書いてあります.1、すべてのjsオブジェクトのプロトタイプチェーンの最後は同じオブジェクト、すなわちObjectのプロトタイプ属性であり、これはなぜ--00--を出力するのですか?
2、コンストラクタデフォルトのprototypeはObjectの一例で、この関数が作成したインスタンスはすべて同じオブジェクトを共有します.
3、Objectのprototype機能を修正するのは強大で、結果が深刻で、慎重です.
4、global-00を出力したのは変数を検索する時、windowのプロトタイプチェーンでxxxを見つけたからです.詳細はjs変数検索規則を研究してください.
5、各関数にはprototype属性があり、関数も対象であるため、プロトタイプチェーンもあります.関数をオブジェクトとして使用すると、プロトタイプチェーン上で属性検索が行われ、関数を構成関数として使用すると新しいオブジェクトが作成され、プロトタイプとして関数のプロトタイプが使用されます.
6、以上の実験はchrome 25バージョンを使って、IEブラウザには一定の出入りがあります.特に可愛いIE 6、7、8.良いニュースはwin xpが歴史の舞台から退出するので、IE 6、7、8もいっしょに歩くべきでしょう.
longsu 2010 at yeah dot net私のメールボックスで、用事があったらメールしないでください.
原型についてはまだたくさんの内容がありますが、本文とはそんなに関係がないので、もう書くことができません.