Javascript乱弾設計モードシリーズ(0)-対象基礎及びインターフェースと継承類の実現
10858 ワード
理論知識
1.まずJavascriptは弱いタイプの言語で、変数を定義する時は声明のタイプは必要ありません.例えば、var Person=new Person()のように、変数のタイプは「var」です.今のC鑰3.0もこの匿名タイプの概念を導入しています.弱いタイプの変数は非常に柔軟性があります.Javascriptは必要に応じてタイプを変換します.したがって、これは遅いバインディングの方法を採用することを決定しました.すなわち、実行後に変数の種類を知ることができます.
2.対象に向かう概念は言うまでもなく、パッケージ、継承、多状態である.
3.Javascriptオブジェクトのタイプは主に三つに分けられます.ローカルオブジェクト、例えばString、Aray、Dateなどです.Global,Mathなどのオブジェクトを内蔵します.宿主の対象は、BOM、DOMの対象などです.変数の範囲は、従来のオブジェクト指向プログラム設計における作用領域を含み、公有、保護、私有、静的など.
主な内容
1.Javascriptがどのようにオブジェクトを作成したかを見てみましょう.
このような種類は伝統的な種類と似ているように見えますか?
2.次のこれは本編の一つのポイントです.Javascriptでインターフェースをどのように設計し、それをクラスに引き継がせますか?
まず、伝統的なC〓言語はどのようにインタフェースを設計しているかを見ましょう.
インターフェースでは、属性、方法、イベント、タイプを宣言することができますが、変数を宣言することはできません.しかし、これらのメンバーの具体的な値を設定することはできません.つまり、定義するだけで、定義されたものに値を付けることはできません.インターフェースは、その後継クラスまたは派生クラスの規約として、継承クラスまたはその派生クラスは、インターフェース属性、方法、方法、イベントとタイプの具体的な実装は、ここでGetName()は、SetName()は、メソッド名と属性呼び出し順序とが一致しているためである.
このようなインターフェースベースの思想があります.Javascriptのインターフェースクラスを設計する時もこの仕様を考慮しなければなりません.まずメインJSファイルの呼び出しから話します.
このうち、Interface類は後で言うインターフェース類で、最初のパラメータ「Person」はインターフェース類の名称で、二つ目のパラメータは二次元配列で、「getName」はインターフェース方法の名前で、「0」はこの方法が持つパラメータの個数です.同理このようなインターフェースが定義されました.どう使いますか?
Manの構造関数に含まれているのを見ました.
Interface.register Implements(this、Person);
これは、実用化されたthisオブジェクトをPersonインターフェースに継承し、クラスを引き継いでインターフェースを行う方法である.
コードはクリアでシンプルに見えますか?では、本格的なコアコードInterface.jsを紹介します.
まず、Interfaceの構造関数の部分を見ます.
先ほどvar Person=new Interfaceを見ました.ここで二つのパラメータを別々に保存します.
コール方法の一部:
先ほどのこのInterface.register Implements;実際にここでは、thisオブジェクトの方法名とパラメータの個数を、Personに保存されたばかりのmethodsと逐一比較しています.見つけられないか、合わないかは、エラーを警告します.ここで、object[method].get Parameeters().lengthは、以下のコードを呼び出します.
getParameters()メソッドは、Functionオブジェクトの拡張として機能し、メソッドに含まれるパラメータ配列を取得する.
Interface.jsの完全なコードは以下の通りです.
もう一つのhtmlページを作成して効果を試してみます.
最終結果は、「Leepy」のポップアップボックスです.
ここでもう一つのポイントを強調したいのですが、もしインターフェース上の方法が継承クラスで完全に実現されていない場合、あるいは方法パラメータの個数が一致しない場合、エラーを提示します.3.もし私が他のクラスに継承したいなら、どうすればいいですか?例を見続けて、ここでSchoolBoy(男子学生)クラスを定義します.
そのうちMan.cal(this);実際にManのキーワードthisをSchoolBoyのオブジェクトに割り当てます.SchoolBoyはManの構造関数のname属性を持っています.
School Boy.prototype=new Man()実際にManのprototypeをSchoolBoy.prototypeに値付けします.School BoyはManの種類の中の方法があります.
後に続くgetName()、setName()は、実際にManクラスを継承する前の方法をカバーしています.
そして効果を見ます.
http://www.CodeHighlighter.com/
最後の結果は「Mr周杰倫's」のポップアップボックスです.
締め括りをつける
この文章は主にいくつかのJavascriptが対象に向かう基礎とインターフェースと継承類の実現などを述べます.次のページは本格的なJavascriptデザインモードの征途を開始します.そして、いくつかのウェブサイトシステムの実例と関連して話します.
本論文はhttp://www.cnblogs.com/liping13599168/archive/2009/01/03/1367334.htmlから来ている.
1.まずJavascriptは弱いタイプの言語で、変数を定義する時は声明のタイプは必要ありません.例えば、var Person=new Person()のように、変数のタイプは「var」です.今のC鑰3.0もこの匿名タイプの概念を導入しています.弱いタイプの変数は非常に柔軟性があります.Javascriptは必要に応じてタイプを変換します.したがって、これは遅いバインディングの方法を採用することを決定しました.すなわち、実行後に変数の種類を知ることができます.
2.対象に向かう概念は言うまでもなく、パッケージ、継承、多状態である.
3.Javascriptオブジェクトのタイプは主に三つに分けられます.ローカルオブジェクト、例えばString、Aray、Dateなどです.Global,Mathなどのオブジェクトを内蔵します.宿主の対象は、BOM、DOMの対象などです.変数の範囲は、従来のオブジェクト指向プログラム設計における作用領域を含み、公有、保護、私有、静的など.
主な内容
1.Javascriptがどのようにオブジェクトを作成したかを見てみましょう.
function Man() {
//
}
Man.prototype.getNickName = function() {
return "Leepy";
};
var man = new Man();
var name = man.getNickName();
このようにして、最も簡単なクラスとオブジェクトを作成しました.ここでfunction Man(){}をMan類の構造関数と見なし、getNickName()をMan類と見なす方法は、正確にはMan類の公共方法として考えられます.なぜですか?それはJavascriptが実際に共有している区分が一つもないので、開発者が自分でこのようなルールを指定しました.ここでMan類のリストを完全に並べます.function Man() {
//
var Sex = " ";
//
function checkSex() {
return (Sex == " ");
}
//
this._getSex = function() {
//
if(checkSex())
return " ";
else
return " ";
}
//
this.getFirstName = function() {
return "Li";
};
//
this.getLastName = function() {
return "Ping";
};
}
//
Man.prototype.getNickName = function() {
return "Leepy";
};
//
Man.prototype.getFullName = function() {
return this.getFirstName() + " " + this.getLastName();
};
//
Man.prototype.getSex = function() {
//
return this._getSex();
};
//
Man.say = function() {
return "Happy new year!";
}
このような種類は伝統的な種類と似ているように見えますか?
2.次のこれは本編の一つのポイントです.Javascriptでインターフェースをどのように設計し、それをクラスに引き継がせますか?
まず、伝統的なC〓言語はどのようにインタフェースを設計しているかを見ましょう.
public interface Person
{
string GetName();
void SetName(string name);
}
public class Man : Person
{
private string _name;
public string GetName()
{
return _name;
}
public void SetName(string name)
{
_name = name;
}
}
インターフェースでは、属性、方法、イベント、タイプを宣言することができますが、変数を宣言することはできません.しかし、これらのメンバーの具体的な値を設定することはできません.つまり、定義するだけで、定義されたものに値を付けることはできません.インターフェースは、その後継クラスまたは派生クラスの規約として、継承クラスまたはその派生クラスは、インターフェース属性、方法、方法、イベントとタイプの具体的な実装は、ここでGetName()は、SetName()は、メソッド名と属性呼び出し順序とが一致しているためである.
このようなインターフェースベースの思想があります.Javascriptのインターフェースクラスを設計する時もこの仕様を考慮しなければなりません.まずメインJSファイルの呼び出しから話します.
var Person = new Interface("Person", [["getName", 0], ["setName", 1]]);
このうち、Interface類は後で言うインターフェース類で、最初のパラメータ「Person」はインターフェース類の名称で、二つ目のパラメータは二次元配列で、「getName」はインターフェース方法の名前で、「0」はこの方法が持つパラメータの個数です.同理このようなインターフェースが定義されました.どう使いますか?
function Man()
{
this.name = "";
Interface.registerImplements(this, Person);
}
Man.prototype.getName = function() {
return this.name;
};
Man.prototype.setName = function(name) {
this.name = name;
};
Manの構造関数に含まれているのを見ました.
Interface.register Implements(this、Person);
これは、実用化されたthisオブジェクトをPersonインターフェースに継承し、クラスを引き継いでインターフェースを行う方法である.
コードはクリアでシンプルに見えますか?では、本格的なコアコードInterface.jsを紹介します.
まず、Interfaceの構造関数の部分を見ます.
function Interface(name, methods)
{
if(arguments.length != 2) {
throw new Error(" " + arguments.length + " , 2 .");
}
this.name = name;
this.methods = [];
if(methods.length < 1) {
throw new Error(" .");
}
for(var i = 0, len = methods.length; i < len; i++) {
if(typeof methods[i][0] !== 'string') {
throw new Error(" .");
}
if(methods[i][1] && typeof methods[i][1] !== 'number') {
throw new Error(" .");
}
if(methods[i].length == 1) {
methods[i][1] = 0;
}
this.methods.push(methods[i]);
}
};
先ほどvar Person=new Interfaceを見ました.ここで二つのパラメータを別々に保存します.
コール方法の一部:
Interface.registerImplements = function(object) {
if(arguments.length < 2) {
throw new Error(" 2 .");
}
for(var i = 1, len = arguments.length; i < len; i++) {
var interface = arguments[i];
if(interface.constructor !== Interface) {
throw new Error(" 2 .");
}
for(var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++) {
var method = interface.methods[j][0];
if(!object[method] || typeof object[method] !== 'function' || object[method].getParameters().length != interface.methods[j][1]) {
throw new Error(" " + interface.name + " " + method + ", .");
}
}
}
};
先ほどのこのInterface.register Implements;実際にここでは、thisオブジェクトの方法名とパラメータの個数を、Personに保存されたばかりのmethodsと逐一比較しています.見つけられないか、合わないかは、エラーを警告します.ここで、object[method].get Parameeters().lengthは、以下のコードを呼び出します.
Function.prototype.getParameters = function() {
var str = this.toString();
var paramString = str.slice(str.indexOf('(') + 1, str.indexOf(')')).replace(/\s*/g,''); //
try
{
return (paramString.length == 0 ? [] : paramString.split(','));
}
catch(err)
{
throw new Error(" !");
}
}
getParameters()メソッドは、Functionオブジェクトの拡張として機能し、メソッドに含まれるパラメータ配列を取得する.
Interface.jsの完全なコードは以下の通りです.
Interface.js
function Interface(name, methods)
{
if(arguments.length != 2) {
throw new Error(" " + arguments.length + " , 2 .");
}
this.name = name;
this.methods = [];
if(methods.length < 1) {
throw new Error(" .");
}
for(var i = 0, len = methods.length; i < len; i++) {
if(typeof methods[i][0] !== 'string') {
throw new Error(" .");
}
if(methods[i][1] && typeof methods[i][1] !== 'number') {
throw new Error(" .");
}
if(methods[i].length == 1) {
methods[i][1] = 0;
}
this.methods.push(methods[i]);
}
};
Interface.registerImplements = function(object) {
if(arguments.length < 2) {
throw new Error(" 2 .");
}
for(var i = 1, len = arguments.length; i < len; i++) {
var interface = arguments[i];
if(interface.constructor !== Interface) {
throw new Error(" 2 .");
}
for(var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++) {
var method = interface.methods[j][0];
if(!object[method] || typeof object[method] !== 'function' || object[method].getParameters().length != interface.methods[j][1]) {
throw new Error(" " + interface.name + " " + method + ", .");
}
}
}
};
Function.prototype.getParameters = function() {
var str = this.toString();
var paramString = str.slice(str.indexOf('(') + 1, str.indexOf(')')).replace(/\s*/g,''); //
try
{
return (paramString.length == 0 ? [] : paramString.split(','));
}
catch(err)
{
throw new Error(" !");
}
}
もう一つのhtmlページを作成して効果を試してみます.
<script type="text/javascript">
function test()
{
var man = new Man();
man.setName("Leepy");
alert(man.getName());
}
</script>
<input type="button" value="click" onclick="test();" />
最終結果は、「Leepy」のポップアップボックスです.
ここでもう一つのポイントを強調したいのですが、もしインターフェース上の方法が継承クラスで完全に実現されていない場合、あるいは方法パラメータの個数が一致しない場合、エラーを提示します.3.もし私が他のクラスに継承したいなら、どうすればいいですか?例を見続けて、ここでSchoolBoy(男子学生)クラスを定義します.
function SchoolBoy(classNo, post)
{
Man.call(this);
this._chassNo = classNo;
this._post = post;
}
SchoolBoy.prototype = new Man();
SchoolBoy.prototype.getName = function() {
return "Mr " + this.name;
}
SchoolBoy.prototype.setName = function(name) {
this.name = name + "'s";
}
そのうちMan.cal(this);実際にManのキーワードthisをSchoolBoyのオブジェクトに割り当てます.SchoolBoyはManの構造関数のname属性を持っています.
School Boy.prototype=new Man()実際にManのprototypeをSchoolBoy.prototypeに値付けします.School BoyはManの種類の中の方法があります.
後に続くgetName()、setName()は、実際にManクラスを継承する前の方法をカバーしています.
そして効果を見ます.
var schoolboy = new SchoolBoy(" ", " ");
schoolboy.setName(" ");
alert(schoolboy.getName());
Code highlighting produced by Actipro CodeHighlighter(freew)http://www.CodeHighlighter.com/
最後の結果は「Mr周杰倫's」のポップアップボックスです.
締め括りをつける
この文章は主にいくつかのJavascriptが対象に向かう基礎とインターフェースと継承類の実現などを述べます.次のページは本格的なJavascriptデザインモードの征途を開始します.そして、いくつかのウェブサイトシステムの実例と関連して話します.
本論文はhttp://www.cnblogs.com/liping13599168/archive/2009/01/03/1367334.htmlから来ている.