如何正确使用 eval() 将动态加载的脚本内容附加到正在构造的对象中?

How can I use eval() properly to append a dynamically loaded script's contents to an object being constructed?

如何正确使用 eval() 将动态加载脚本的内容附加到正在构造的对象中?

我正在开发 require 的简单实现,供我自己的客户端使用。为此有多个库,但为了学习,我正在编写一个非常简单的库。

此代码应创建一个模块 playBall 并且在同一步骤中需要包含代码的两个模块来创建和移动球。

所以我需要两个简单的模块(文件):

example.com/createBall.js:

var exports = {};
var exports.createBall = function (){ 
    $("body").append("<div id=\'ball\'></div>") 
}

example.com/moveBall.js:

var exports = {};
var exports.moveBall = function (){ 
    $("#ball").animate({ marginTop : 300 },500) 
}

这个 require 函数只是根据传递给 Module 构造函数的位置执行 AJAX 调用来抓取脚本。

var Library = {};

// ..snip.. (The code within the mockAJAXCall is irrelevant)

//define resource requirement functionality
Library.require = function (resourceName, callback) {
    Library.mockAJAXCall(resourceName, function (mockResponse) {

        //return the response to the module requiring the resource
        callback(mockResponse);
    });

};

//define module prototype
Library.Module = function () {
    var _this = this;
    this.resources = {};
    for (var i = 0; i < arguments.length; i++) {
        Library.require(arguments[i], function (resource) {
            _this.resources[resource.location] = resource;
            for (var i in _this.resources){
                eval(); // ! eval the resource in a way that assigns 
                        // all of the functions and variables to _this
            }
        });
    }
};

//utilize requirement
var playBall = new Library.Module('example.com/createBall.js', 
    'example.com/moveBall.js');

playBall.createBall();
playBall.moveBall();
#ball {
    width:100px;
    height:100px;
    border-radius:100px;
    background-color:red;
    border-style:solid;
    border-color:maroon;
}

该片段的重要部分是:

for (var i = 0; i < _this.resources.length; i++){
    eval(); // ! eval the resource in a way that assigns 
            // all of the functions and variables to _this
}

我不确定如何 eval() 所需的脚本,以便每个 exports 对象的内容附加到 _this 对象。

我建议使用 Function constructor 而不是 eval(尽管您可以对经过评估的 IEFE 执行相同的操作)。这样,你

  • 免费获得 "module" 瞄准镜
  • 不要与加载函数的作用域发生冲突
  • 可以传递任意名称的参数

(new Function("exports", ressourceCode))(ressourceObject);