向现有对象添加方法

时间:2018-07-23 08:32:25

标签: javascript

这是我一年多以前问的一个问题的演变:How to create methods with a loop in jquery/javascript

我有一个与其他同事共享的代码,所以最好更改不多。它是这样的:

var scriptList = {
    components : [
        'all'
    ],
    modules : [
        'one',
        'two',
        'three'
    ]
}

function core() {
    var scope = this;

    var promises = [];
    jQuery.each(scriptList, function(key, value) {
        jQuery.each(value, function (index, name) {

            var hookValue = 'hook_'+name,
                stringValue = 'string_'+name,
                argsValue = 'args_'+name;

            scope[name] = function(callback){
                window[hookValue] = jQuery('.js-'+name),
                window[stringValue] = 'js-'+name;
                window[argsValue] = arguments;

                loadAndUse(window[hookValue],key+'/'+name,callback);
            }

            if(key === 'modules'){
                scope[name]();
            }
        });
    });

    jQuery.when.apply(jQuery, promises).then(function() {
        window.executeReady = true;
    });
}

ui = new core();

ui.exec = methodLoader;
ui.exec();

此代码可以正常工作,因为我可以使用添加到ui.one-ui.two等中的各种方法,依此类推,如果执行console.log(ui),也可以登录到控制台。

在此代码被触发之前,我现在在 HTML页面中还有另一个代码块,该代码块创建了一个称为ui的方法(始终是exec对象) :

window.executeReady = false;

var ui = {},
    scriptToBeLoaded = [];

var methodLoader = function(){
    var scope = this;

    this.exec = function(module, callback){
        scriptToBeLoaded.push({
            'module'    : module,
            'callback'  : callback
        });

        if(module === undefined){
            console.warn('This module does not exists. Please check the scriptList.');
        } else {
            function waitForList($context, $variable, $callback) {
                if ($context[$variable]) {
                    $callback();
                } else {
                    Object.defineProperty($context, $variable, {
                        configurable: true,
                        enumerable: true,
                        writeable: true,
                        get: function() {
                            return this['_' + $variable];
                        },
                        set: function(val) {
                            this['_' + $variable] = val;
                            $callback();
                        }
                    });
                }
            }

            waitForList(window, 'executeReady', function(){
                for (var i = 0; i < scriptToBeLoaded.length; i++) {
                    ui[scriptToBeLoaded[i].module](scriptToBeLoaded[i].callback);
                }

                scriptToBeLoaded = [];
            });
        }
    };
};

ui = new methodLoader();

由于这段代码,当我console.log(ui);时,我只看到exec方法,其他所有方法都消失了。虽然,我在core()函数中创建的方法可以正确执行,但在ui对象中不存在。

我想编辑HTML页面中的代码,以使ui对象与exec(在html端创建)和其他方法(在js文件中创建) )全部放在ui对象中。

我该如何实现?

1 个答案:

答案 0 :(得分:0)

您可以像这样向现有对象添加新方法。或者,您可以使用jQuery.extend()合并两个对象。

var ui = ui || {},
scriptToBeLoaded = [];

ui.exec = function(module, callback){
        scriptToBeLoaded.push({
            'module'    : module,
            'callback'  : callback
        });

        if(module === undefined){
            console.warn('This module does not exists. Please check the scriptList.');
        } else {
            function waitForList($context, $variable, $callback) {
                if ($context[$variable]) {
                    $callback();
                } else {
                    Object.defineProperty($context, $variable, {
                        configurable: true,
                        enumerable: true,
                        writeable: true,
                        get: function() {
                            return this['_' + $variable];
                        },
                        set: function(val) {
                            this['_' + $variable] = val;
                            $callback();
                        }
                    });
                }
            }

            waitForList(window, 'executeReady', function(){
                for (var i = 0; i < scriptToBeLoaded.length; i++) {
                    ui[scriptToBeLoaded[i].module](scriptToBeLoaded[i].callback);
                }

                scriptToBeLoaded = [];
            });
        }
    };