0

私は小さなヘルパー ライブラリを自分で構築しようとしています。最初は学習目的で、後でプロジェクトで役立つように拡張できます。

プロトタイプの参照、クロージャー、スコープについてある程度理解しています。toolboxまた、グローバル名前空間を汚染しないように、意図的にモジュール パターンを使用して作成しました。また、プロトタイプをコンストラクター関数に割り当てることができることも知っているので、構築されたオブジェクトはそれらのメソッドを保持します。

の内容はこちらtoolbox.js

(function (window) { 
var toolbox = (function () { 
    var toolbox = function(it){
            return new pick(it);
    }
    var pick = function (it){
        var craft = document.getElementsByTagName(it);
        craft = Array.prototype.slice.call(craft, 0);
        return Array.prototype.push.apply(this, craft);
    }

    pick.prototype = toolbox.prototype = {
        raw: function(){
            return Array.prototype.slice.call(this, 0);
        }, 
        tell: function(secret){
            return secret;
        }
    }

    return toolbox;
}());
window.toolbox = toolbox;
})(window);

と呼び出すtoolbox

toolbox("div"); //returns the desired object with the div collection
toolbox("div").raw(); //returns a raw array with the divs
toolbox().tell("A secret"); //returns "A secret"
toolbox.tell("It's a secret"); //type error: the function has no method like tell (like hell it does...should)

ただし、上記のコードを次のように変更します。

var toolbox = (function () { 
    var toolbox = function(it){
    return new pick(it);
}
     ...
    toolbox.tell(secret){ return secret }
return toolbox;
}());

動作します。

だから私の質問は、定義されたメソッドを継承するのに、なぜtoolbox.prototype = {} トリックをしないのですか?pick.prototype = {}pick

メソッドをモジュールに直接プロトタイピングすることを解決する必要なく、両方を実現し、可能にしtoolbox.tell("something");たいと考えています。toolbox("div").raw();

助けてください!私はこれらを学ぶために何日もグーグルで検索してきましたが、今は立ち往生しています。あなたの助けは大歓迎です!

アップデート

jQuery でこれを行う方法を簡単に説明すると、次のようになります。

(function( window, undefined ) {
    var jQuery = (function() {
        // Define a local copy of jQuery
        var jQuery = function( selector, context ) {
                // The jQuery object is actually just the init constructor 'enhanced'
                return new jQuery.fn.init( selector, context, rootjQuery );
            }   

        jQuery.fn = jQuery.prototype = {
            constructor: jQuery,
            init: function( selector, context, rootjQuery ) {
                //init stuff
            }
        };

        // Give the init function the jQuery prototype for later instantiation
        jQuery.fn.init.prototype = jQuery.fn;

        jQuery.extend = jQuery.fn.extend = function() {
            //extend stuff
        };

        jQuery.extend({
            //extend stuff
        });

    // Expose jQuery to the global object
    return jQuery;

    })();
window.jQuery = window.$ = jQuery;
})(window);
4

3 に答える 3

2

プロトタイプにある場合とオブジェクト自体にある場合には違いがあります。

次の例を考えてみましょう。

var foo = function() { return 'I am foo'; }

foo.prototype.lie = function() { return 'I am not foo'; }
foo.lie(); //error, lie does not exist in foo

var bar = new foo;
bar.lie(); //it works!

prototype基本的には親と子の中間です。プロトタイプには、親が持っているものすべてに加えて、追加したものがありますが、親には独自のプロトタイプはありません。さらに混乱させるために、プロトタイプではなく親オブジェクトにコンテンツを割り当てた場合、余分なものは子にコピーされません。変だよね?

最後のステートメントを説明するには(前の例を使用):

foo.makeAPoem = function() { return 'Roses are red, violets are blue, coffe milk eggs'; }
var bar = new foo;
foo.makeAPoem(); //works
bar.makeAPoem(); //nope!

String.splitたとえば、これがないのはまさにそのためですが、'abcd'.splitこれらのメソッドはプロトタイプに存在します。

オブジェクトとプロトタイプの両方で何かを機能させたい場合は、両方に割り当ててください。

foo.jedi = foo.prototype.jedi = function() { return 'This is not the function you are looking for'; }
foo.jedi(); //works
bar.jedi(); //works!

これで、何を継承し、何を親に残すかを選択できます。親だけが利用できるようにしたい場合は、親にのみ追加してください。ただし、子でのみ使用できるようにする場合(たとえば、はありませんがjQuery.andSelf、jQuery()。andSelfはあります)、プロトタイプに追加します。両方が必要な場合は、両方に追加します。

于 2011-06-01T05:50:31.947 に答える
0

この理由は、pickのようなコンストラクターのように、ツールボックスがインスタンス化されなかったためです。シンプルなソリューション。

それ以外の

pick.prototype = toolbox.prototype = {
....
...
return toolbox;

ただ使う

pick.prototype = {
....
....
for(var attr in pick.prototype) {
  toolbox[attr] = pick.prototype[i];
}

これにより、メソッドがツールボックスに直接追加されます

于 2011-06-01T05:51:15.547 に答える
0

次のようなパワーコンストラクターを定義できます(実際にそのように呼び出されているかどうかはわかりません=))。

var toolbox = (function(){
 // some private methods
   var test_1 = function(){ alert("test_1"); };
   var test_2 = function(){ alert("test_1"); };
 // return needed methods and props into the global namespace: 
   return {
    "test_1" : test_1,
    "test_2" : test_2
   }
})();

toolbox.test_1();
于 2011-06-01T05:38:56.070 に答える