JavaScriptのprototype(インスタンス)について

12675 ワード

JSのphotototypeはJSの中で比較的理解しにくい部分です.JAvascriptのメソッドは,クラスメソッド,オブジェクトメソッド,プロトタイプメソッドの3つに分類できる.
例:
function People(name)
{
	this.name=name;
	//    
	this.Introduce=function(){
		alert("My name is "+this.name);
	}
}
//   
People.Run=function(){
	alert("I can run");
}
//    
People.prototype.IntroduceChinese=function(){
	alert("     "+this.name);
}

//  
var p1=new People("Windking");
p1.Introduce();
People.Run();
p1.IntroduceChinese(); 
 
obj1.func.call(obj)メソッドはobjをobj 1と見なしfuncメソッドを呼び出すことを意味する.
prototypeとはどういう意味ですか
JAvascriptの各オブジェクトにはprototypeプロパティがあり、Javascriptのオブジェクトのprototypeプロパティの解釈は、オブジェクトタイプのプロトタイプの参照を返すことです.
A.prototype = new B();
 
prototypeが継承と混同すべきではないことを理解します.AのprototypeはBの一例であり、AがBの方法と属性をすべてクローンしたことが理解できる.AはBの方法と属性を使うことができます.ここで強調するのは、継承ではなくクローンです.この場合、AのprototypeはBのインスタンスであり、BのprototypeもAのインスタンスである.
まず実験の例を見てみましょう.
function baseClass()
{
	this.showMsg = function()
	{
     	alert("baseClass::showMsg");   
	}
}

function extendClass()
{
	
}

extendClass.prototype = new baseClass();
instance = new extendClass();
instance.showMsg(); //   baseClass::showMsg
 
まずbaseClassクラスを定義し、extentClassを定義しますが、baseClassのインスタンスをモデルにしてクローン化するextendClassにはshowMsgというオブジェクトメソッドも含まれています.extendClass.prototype=new baseClass()は、extendClassがbaseClassのインスタンスをプロトタイプとしてクローン作成されたものであると読むことができます.
では、extendClassにbaseClassと同じ名前のメソッドが含まれている場合はどうなりますか?
次は拡張実験2です.
function baseClass()
{
    this.showMsg = function()
    {
        alert("baseClass::showMsg");   
    }
}

function extendClass()
{
    this.showMsg =function ()
    {
        alert("extendClass::showMsg");
    }
}

extendClass.prototype = new baseClass();
instance = new extendClass();

instance.showMsg();//  extendClass::showMsg
 
実験により,関数の実行時に本体の関数を先に探し,見つかったら実行し,見つからなければprototypeで関数を探すことが証明された.あるいはprototypeは同名関数をクローンしないと理解できます.
では、extendClassのインスタンスinstanceを使用してbaseClassのオブジェクトメソッドshowMsgを呼び出すにはどうすればいいのでしょうか.
答えはcallを使用できます.
extendClass.prototype = new baseClass();
instance = new extendClass();

var baseinstance = new baseClass();
baseinstance.showMsg.call(instance);//  baseClass::showMsg
 
ここのbaseinstanceshowMsg.call(instance);「instanceをbaseinstanceとして呼び出し、そのオブジェクトメソッドshowMsgを呼び出す」と読みます.なぜbaseClassを使わないのかと聞かれるかもしれませんshowMsg.call(instance);これがオブジェクトメソッドとクラスメソッドの違いです.baseClassのオブジェクトメソッドを呼び出します.
最後に、次のコードを理解すれば、この文章の言うことはすでに理解されています.
<script type="text/javascript">
function baseClass()
{
    this.showMsg = function()
    {
        alert("baseClass::showMsg");   
    }
   
    this.baseShowMsg = function()
    {
        alert("baseClass::baseShowMsg");
    }
}
baseClass.showMsg = function()
{
    alert("baseClass::showMsg static");
}

function extendClass()
{
    this.showMsg =function ()
    {
        alert("extendClass::showMsg");
    }
}
extendClass.showMsg = function()
{
    alert("extendClass::showMsg static")
}

extendClass.prototype = new baseClass();
instance = new extendClass();

instance.showMsg(); //  extendClass::showMsg
instance.baseShowMsg(); //  baseClass::baseShowMsg
instance.showMsg(); //  extendClass::showMsg

baseClass.showMsg.call(instance);//  baseClass::showMsg static

var baseinstance = new baseClass();
baseinstance.showMsg.call(instance);//  baseClass::showMsg

</script>
 
ソース:http://www.nowamagic.net/javascript/js_KnowAboutPrototype.php
 
例1:テキストの自動反転
 
JAvascriptのprototypeに関する簡単な例は具体的に以下の通りです.prototypeはjavascriptのプロトタイプ属性です.この属性によって、私たちは方法を拡張することができます.以下の例は主にstringに逆属性を追加することによって、この方法を呼び出すと、テキストは自動的に逆属性を取ります.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title></title>
    <script type="text/javascript">
    //            
    function outputbackwards(){
    for (i=this.length-1;i>=0;i--)
    document.write(this.charAt(i))
    }
    // stirng       
    String.prototype.writeback=outputbackwards
    </script>
</head>
<body>
<script type="text/javascript">
var message1="Welcome to my site!"
message1.writeback()//    
var message2="Today is a beautiful day"
message2.writeback()
</script>
</body>
</html>
 
例2:JavaScriptでjQueryの表示と非表示を実現
 
jQueryではshow()、hide()、slideDown()、slideUp()などの方法があり、DOM要素をアニメーション形式で表示または非表示にすることができます.このようなアニメーションはページインタラクションでよく使われており、これもjQueryが開発しやすい場所の一つですが、これらのアニメーション効果だけを使ってjQueryライブラリ全体をロードしたい場合はリソースがもったいないので、オリジナルのJavaScriptでこのようなjQueryアニメーションを実現してみてください.オリジナルJavaScriptコードを紹介する前にKayoが質問したいのは、jQueryのJavaScriptに対する優位性とは何ですか?開発者がjQueryを理解してからオリジナルJavaScriptを学ぶと、以下の利点がわかりやすくなります.
強力で柔軟なセレクタは、多くのJavaScriptクラスライブラリのようにjQueryが$()関数をセレクタとして使用する、JavaScriptのdocumentよりもCSS 1からCSS 3のセレクタをサポートする.getElementById(), document.getElementsByTagName()は、このようなセレクタが便利であることは間違いありません.
いくつかのアニメーションメソッドを含む、一般的なイベント、メソッドがあります.
完璧なパッケージ、jQueryの中のオブジェクト処理、伝達、操作はすべて完璧なパッケージと処理メカニズムを持っていて、しかも異なるブラウザに対する互換性をよくして、これらはもし原生のJavaScriptを使って書き換えるならば1種の非常に重い仕事です.
もちろん、jQueryの劣勢も明らかです.あなたのサイト全体がjQueryのいくつかのアニメーション方法を使用しているだけでも、100 K近くのライブラリファイルをロードします.次は、上記の点を考えて次の文を読むと、jQueryの使い勝手がわかります.最初に議論した問題に戻ります.オリジナルのJavaScriptを使ってjQueryアニメーションを実現すると、次はコードが放出されますが、コードがカプセル化されているため、具体的なプロセスはコードで理解しにくいので、ここで簡単に説明します.
 
1.アニメーションオブジェクトを作成する——Transform、いくつかの方法を追加する:アニメーション形式はDOM要素を隠すアニメーション形式はDOM要素を表示する
2.DOM要素オブジェクトを作成します.$を追加します.idのDOM要素を取得し、その要素のCSSアニメーション形式の非表示要素を取得します(Transformオブジェクトをインスタンス化し、その中の方法を呼び出します)アニメーション形式の表示要素(Transformオブジェクトをインスタンス化し、その中の方法を呼び出します)
 
3.実際に操作する必要があるDOM要素idに基づいて$オブジェクトをインスタンス化し、対応するメソッドを呼び出すと、上記のメソッドは少し厄介ですが、なぜ直接$オブジェクトにアニメーションメソッドを書かないのでしょうか.このように書くのは、オブジェクトのメンテナンスと独立性の向上を容易にするためです.たとえば、アニメーションオブジェクトにアニメーションメソッドを追加したり、Dom要素オブジェクトに操作を追加したりすると、2つの異なるオブジェクトにカプセル化するとメンテナンスが容易になります.簡単なアニメーション効果を使いたいだけなら、完全に異なるパッケージを作ることができます.結局、パッケージ後の効率は大幅に低下します.もちろん、この効率の違いはPCで直接見ることは難しいです.以下に具体的な方法とコードを与える:アニメーションを実現する原理は簡単である--特定の単位時間で連続的に1組の静的画面を再生し、JavaScriptではwindowを利用することができる....setIntervalはこの効果を実現し、ここでKayoはwindowを採用する.settimeoutは、要素の幅と高さを低減する方法を再帰的に呼び出して実現する.なお、アニメーションを実装する方法では、DOMオブジェクトのidを渡すのではなく、操作するDOMオブジェクトを直接渡すべきであるため、DOMを取得する方法を書くことが望ましい.アニメーションは、Webページに同時に作用する複数の要素であるため、グローバル変数の使用は避けられます.関数をカプセル化する際に使用すべきである.prototypeの追加方法で、メモリを節約します.これらのJavaScriptは書き終わったらヘッダーではなくfooterに置くべきで、オリジナルJavaScriptには持参した関数がないのでページごとにDOMがロードされたかどうかをチェックするので、JavaScriptを最後に書くべきで、もちろん開発者はページのDOMがロードされたかどうかを判断する関数を別に書くこともできます.ここでは、DOM要素の非表示を例に、DOM要素をアニメーション形式で非表示にする方法を含むアニメーションオブジェクトを作成します.アニメーションオブジェクトのインタフェースでは、objは操作が必要なDOMオブジェクトであり、speedはアニメーション速度であり、数値が小さいほどアニメーションが速くなり、modeはアニメーション方式であり、「zoom」、「slide」の2つの方式があり、それぞれjQueryにおけるhide()とslideUp()の効果をシミュレートし、fnはコールバック関数である.また、hide()のwidthとheightの2つのパラメータはDOM要素の幅と高さであり、DOM要素オブジェクトでhide()が呼び出されたときに割り当てられます.
//       
var Transform = function(obj, speed, mode, fn){
    this.obj = obj;
    this.speed = speed; //     
    this.mode = mode;   //     
    this.heightChange = 10;
    this.fn = fn;
    if( speed === 'fast')
        this.speed = 10;
    else if( speed === 'normal' )
        this.speed = 20;
    else if( speed === 'slow' )
        this.speed = 30;
}
Transform.prototype = {
    //     
    hide: function( width, height ){
        var self = this;
        if ( !this.speed ) {
            this.obj.style.display = 'none';
            return;
        }
        width = width - this.widthChange &gt; 0 ? width - this.widthChange : 0;
        height = height - this.heightChange &gt; 0 ? width - this.heightChange : 0;
        //
        if( width !== 0 || height !== 0 ) {
            //           
            if( this.mode === 'zoom' ) this.obj.style.width = width + 'px';
            this.obj.style.height = height + 'px';
            //       
            setTimeout(function(){self.hide(width,height)},this.speed);
        } else {
            //         style   
            this.obj.style.cssText = &quot;&quot;;
            //    display: none
            this.obj.style.display = 'none';
            if(this.fn) this.fn.call(this.obj);
        }
    }
}
 
次はDOMオブジェクトテンプレートの作成です
// DOM       
var $ = function(id){
    this.id = id;
    this.obj = document.getElementById(this.id);
}
$.prototype = {
    //         CSS
    getClass: function(name){
        // IE8     
        if(this.obj.currentStyle) {
            return this.obj.currentStyle[name];
        }
        // Firefox, Chrome, IE9+
        else {
            var style = document.defaultView.getComputedStyle(this.obj, null);
            return style[name];
        }
    },
    //            
    cal: function(speed, mode, fn){
        //       
        this.theTransform = new Transform(this.obj, speed, mode, fn);
        this.theTransform.theWidth = this.getClass('width').replace('px','');
        this.theTransform.theHeight = this.getClass('height').replace('px','');
        //                    
        this.theTransform.widthChange = this.theTransform.heightChange*(this.theTransform.theWidth / this.theTransform.theHeight);
    },
    //     
    hide: function(speed, mode, fn){
        this.cal(speed, mode, fn);
        this.theTransform.hide(this.theTransform.theWidth, this.theTransform.theHeight);
    },
    //     
    show: function(speed, mode, fn){
        this.cal(speed, mode, fn);
        this.theTransform.show(0, 0);
    }
}
 
ここでは1つのgetCssメソッドを用いてDOM要素の幅と高さを取得し、ブラウザによって取得方式が異なることに注意して判断(jQueryの優位性を感じたでしょう)、また減少するたびに幅widthChangeは要素の幅の割合で算出され、直接指定されたものではなく、jQueryでのアニメーション効果をシミュレートするためです.以下に、jQueryライブラリをロードする必要がなく、このようなアニメーションを使用する必要がある完全なDemoを示します.完全なDemoをダウンロードを使用して、DemoのjsファイルをあなたのWebページに接続してアニメーションを使用することができます.例えば、ネット上にid=「box」のdivがある場合は、以下のJavaScriptとHTMLを使用してdivを隠して表示することができます.操作が必要なDOM要素のidでDOM要素オブジェクトをインスタンス化する
//    DOM     
var theDom = new $('box');
 
対応するHTMLでは、「fast」がアニメーション速度である場合、「normal」、「slow」を選択することもできます.3つの異なる速度を表します.また、直接数値を記入することもできます(50以内であれば、数値が小さいほどアニメーション速度が速くなります)、記入しない場合はアニメーションをキャンセルし、要素を直接隠したり表示したりすることができます.「zoom」はアニメーション形式であり、「slide」を選択することもできます.また、theDomのような選択的なコールバック関数もあります.hide('fast', 'zoom', function(){alert('succeed');}).これらの使用法はDemoを参照することができる.
 
<a href="#" onclick="theDom.hide('fast', 'zoom')">    </a>
<a href="#" onclick="theDom.show('fast', 'zoom')">    </a>

 
ソース:http://kayosite.com/achieve-jquery-animate-by-javascript.html