4

しばらく前に拡張しようとしましたObject.prototype...後でコンソールにjQueryファイルからのエラーが表示されたときは驚きました。私は何が間違っているのかを理解しようとしましたが、もちろん、拡張Object.prototypeは「悪」であるという情報、「JS は動的言語であり、コードがすぐに機能しないため、それを行うべきではありません」という情報と、jQuery がhasOwnPropertyメソッドを追加するという情報を見つけました。彼らのfor inループに。

私は jQuery を離れたくなかったので、拡張についての考えを捨てましたObject.prototype

今まで。私のプロジェクトは大きくなり、コードのいくつかの部分を何度も繰り返さなければならないので、本当にイライラしています。以下は、私のプロジェクトで使用している構造の一部です。

charts.js:

CHARTS = {
    _init: function () {
        this.monthlyChart();
        /*
         * 
         * more propertys goes here
         * 
         */
        return this;
    },
    monthlyChart: function () {
        //create my chart
        return {
            update: function () {
               // update chart
            }
        };
    }()
    /*
     * 
     * more propertys goes here
     * 
     */
}._init;

ダッシュボード.js

NAVBAR = {
    _init: function () {
        /*
         * 
         * more propertys goes here
         * 
         */
        return this;
    },
    doSomething: function(){            
        $(document).ready(function(){
            $('.myButton').on('click', function(){
                var data = [];
                // calling property from charts.js
                CHARTS.monthlyChart.update(data);
            });
        });
    }
}._init

前述したように、プロジェクトは現在非常に大きくなっています。40 以上の js ファイルがあり、そのうちのいくつかには数千行のコードが含まれています。&&_initを繰り返さなければならない多くの機能と同様に、セクションを毎回繰り返さなければならないのは本当に面倒です。$(document).ready$(window).load

私は自分の問題の別の解決策を見つけようとしました。initプロパティを使用してクラスを作成しようとしましたが(詳細はこちらで確認できます)、このソリューションにより、すべてのファイルに別の「不要な」コードを追加する必要があり、他のファイルオブジェクトプロパティへのアクセスも複雑になります(どこでも適切なオブジェクトを返すなど) )。コメントでアドバイスされているように、JS のゲッターとセッターについて読み始めました。

結局、私はそのようなものを作成しました:

 //Auto initialization
if (typeof $document === 'undefined') {
    var $document = $(document),
            $window = $(window),
            $body = $('body');
}

Object.defineProperty(Object.prototype, '_init', {
    get: function () {
        // if object has no property named `_init`
        if (!this.hasOwnProperty('_init')) {
            for (var key in this) {
                // checking if name of property does starts from '_' and if it is function
                if (this.hasOwnProperty(key) && key[0] === '_' && typeof this[key] === 'function') {                    
                    if (key.indexOf('_ready_') > -1) {
                        //add function to document ready if property name starts from '_ready_'
                        $document.ready(this[key].bind(this));
                    } else if (key.indexOf('_load_') > -1) {
                        //add function to window load if property name starts from '_load_'
                        $window.load(this[key].bind(this));
                    } else {
                        // else execute function now
                        this[key].bind(this)();
                    }
                }
            }
            return this;
        }
    }
});

と私のオブジェクト:

var DASHBOARD = {
    _runMe: function(){

    },
    _ready_runMeOnReady: function(){

    },
    _load_runMeOnLoad: function(){

    },
    iAmAString: ''
}._init

このソリューションは jQuery で動作するようです。しかし、安全に使用できますか?コードが引き起こす可能性のある問題は見られず、コードが引き起こす可能性のあるその他の問題も見当たりません。このソリューションを使用すべきではない理由を誰かが教えてくれたら、本当にうれしいです。

また、それがどのように機能するかを詳細に理解しようとしています。理論的には、値を割り当てずにObject.prototypebyのプロパティを定義しました。definePropertyどういうわけか、jQueryfore inループでエラーが発生しないのはなぜですか? _initそれは、私がプロパティのゲッターのみを定義しているため、プロパティがある時点またはまったく定義されていないことを意味しますか?

どんな助けでも大歓迎です:)

4

3 に答える 3

3

JavaScriptに記述子を含めないことにより、Object.defineProperty(obj, prop, descriptor)すべてのブール記述子属性がデフォルトで false になります。すなわち writable、、、enumerableおよびconfigurable。プロパティが であるため、新しいプロパティはfor in反復子から隠されています。_initenumerable:false

私は JQuery のファンではないので、JQuery に関する理由についてはコメントしません。

JavaScript の基本型にプロパティを追加する絶対的な規則はなく、コードが実行されている環境によって異なります。基本型に追加すると、グローバル名前空間に追加されます。アプリケーションがサード パーティのスクリプトと名前空間を共有している場合、競合が発生する可能性があり、コードまたはサード パーティのコード、またはその両方が失敗する可能性があります。

あなたが唯一のコードである場合、競合は問題になりませんが、object.prototype に追加すると、オブジェクトを使用するすべてのコードで追加のオーバーヘッドが発生します。

グローバル _init の必要性を再検討することを強くお勧めします。確かに、新しいオブジェクトが必要になるたびに使用するわけではありません。私は JavaScript データ構造へのアドホック アプローチのファンであり、正式な OOP パラダイムから離れようとしています。

于 2015-05-19T14:24:29.053 に答える