如何在变量中捕获HTML脚本标记的结果?

时间:2017-10-24 18:01:54

标签: javascript asynchronous amd

我一直在阅读有关AMDrequirejs等实施的内容。大多数资源都涵盖了用法和API。

但是,在实现这一点时,如何将JavaScript文件加载到变量中呢?例如,您可以看到如下函数:

define(['jquery'], function($){
});

var jquery = require('./jquery');

从API消费者的角度来看,我能理解的是文件jquery.js神奇地变成了$jQuery等等?这是如何实现的?

任何例子都会有所帮助。

How do AMD loaders work under the hood?是一本有用的读物​​。

编辑:我认为下面的eval答案很好,因为它在某些方面实际上是一个eval问题。但我想从AMD specs实施的角度来了解这一点。

4 个答案:

答案 0 :(得分:3)

您不会将javascript文件加载到变量中,而是由browserify或webpack等内容完成。 Javascript本身可以执行此操作,但这些模块生成包含所有代码的单个文件。通过调用require("file"),您调用browserify的函数来加载存储在代码中的名为“file”的文件。

如果你有一个模块

,可以这样做
function demoModule(){
    console.log("It works!");
}
module.exports = demoModule

这使得module.exports现在包含文件的“整个”内容

Browserify / webpack将其放入一个返回该文件的module.exports的函数

function require(filename) {
    switch(filename){
        case "demofile":
            let module = {exports:{}}; ((module) => {
               function demoModule(){
                   console.log("It works!");
               }
               module.exports = demoModule
            })(module)
            return module.exports;
    }
};
    
require("demofile")();

您的文件将成为可以使用require("demofile")调用的函数,它将返回任何module.export。

答案 1 :(得分:2)

您知道如何说eval(alert("hello!"))并执行代码吗?

你也可以:

var str = "hello!"
eval('alert("' + str + '");')

所以下一步是要有一个包含实际脚本的文件:

var str = "hello"
alert(str)

然后你可以使用标准的AJAX请求将该文件提取到变量中,你可以eval()该变量。

从技术上讲,eval()被认为是邪恶的 - 充满了危险 - 但还有其他解决方案(例如,在文档正文中注入脚本标记)。我刚跟eval()一起去了解这个问题。

答案 2 :(得分:1)

扩展了睡眠所说的内容。

这样的事情:

var str = "if (x == 5) {console.log('z is 42'); z = 42;} else z = 0;";

console.log('z is ', eval(str));

更多阅读here

但请谨慎使用eval()并绝对确定eval()的缺陷和缺点。

除非是唯一的选择,否则不要使用它。

也请阅读此answer

答案 3 :(得分:0)

define在幕后工作的方式不是将“HTML脚本加载到变量”。通常,普通脚本可以有多个变量,因此捕获值变量没有意义!如果需要,eval方法可能会做类似的事情。它捕获JavaScript源代码中的所有内容。

AMD中的真正关键是define API将名称映射到功能。只要您require具有该名称,它就会调用该函数并将值返回给您。此返回值应为模块。这是惯例,使一切正常运作!

换句话说,AMD使用一种有趣的约定(设计模式)来确保我们在JavaScript代码中获得模块化效果。这是一个间接的层面。您只需编写一个函数来返回单个值,该函数将捕获您希望作为模块公开的所有内容传递给消费者,而不是正常的“编写代码并在全局范围内执行”范式。