【问题标题】:Running a javascript function in global scope在全局范围内运行 javascript 函数
【发布时间】:2018-04-24 07:12:52
【问题描述】:

为了符合 GDPR,我将我们网店中的所有附属脚本封装在函数中,并将它们添加到作业队列中。

在用户接受我们的隐私政策后,我会运行所有排队的作业。我想在全局范围中运行它们,因此所有声明的变量都可以在全局范围内访问,因为一些附属脚本依赖于全局变量(我知道这很丑;))。

我知道,我可以重写所有 javascript 代码并在全局范围内声明变量并将其余代码包装在一个函数中。 但是我需要编辑很多外部模块(我们正在运行一个 magento 网上商店并使用外部模块来包含附属脚本)

我目前的做法:

var jobQueue = [];
var add = function (fn) {
    jobQueue.push(fn);
    console.log("function pushed to queue");
};
var execute = function () {
    while ((curJob = jobQueue.pop()) !== undefined) {
        curJob();
        console.log("executed job");
    }
};

我的问题是一些外部脚本取决于我的工作中声明的变量。是否有可能像代码在全局范围内运行一样运行函数?

我已经找到了类似的东西,但我无法让它工作: Javascript eval on global scope? (这不适用于函数)

eval.call(window, x, y, z)

【问题讨论】:

  • addexecute 函数是如何被调用的?
  • 如果它们是你的函数,你可以用不同的方式声明变量(不要使用var)。但老实说,我会摆脱任何需要你的变量是全局的代码。
  • 我也不喜欢它,但我需要这个才能让附属脚本正常工作。由于 gdpr 我更改了我的代码并在用户接受我们的隐私政策后声明/加载变量/脚本......但是......在全局范围内运行的代码现在被包装在一个函数中并稍后调用......但是加载外部附属脚本时,它需要全局范围内的变量
  • 我猜你有很多函数使用相同的变量,所以通过将变量放在全局执行上下文中,所有函数都可以访问变量?
  • @ThumChoonTat 我将我网站上的所有附属脚本包装在一个功能块内,并将它们添加到我的工作队列中......当用户接受隐私政策时(因为 gdpr)我执行所有我的排队作业

标签: javascript


【解决方案1】:

我找到了一个可能的解决方案,但它

我将函数主体 (How to get function body text in JavaScript?) 保存到一个字符串并在窗口范围内对其进行评估

var execute = function () {
    while ((curJob = jobQueue.pop()) !== undefined) {
        var entire = curJob .toString(); 
        var body = entire.slice(entire.indexOf("{") + 1, entire.lastIndexOf("}"));
        eval.call(window, body);
        console.log("executed job");
    }
};

【讨论】:

    【解决方案2】:

    Javascript 中的变量具有“函数范围”,这意味着如果您在函数内部声明变量,则无法从该函数外部访问它。 但是当函数内部不存在变量时,Javascript 会在函数外部查找该变量,直到它到达全局对象。

    所以在全局对象中声明的变量随处可见。

    您可以通过在全局范围内声明变量来将变量分配给全局范围。

    var pushing = "function pushed to queue";
    var executed = "executed job";
    var jobTitle = "... programing ...";
    
    var jobQueue = [];
    var add = function (fn) {
        jobQueue.push(fn);
        console.log( pushing );
    };
    var execute = function () {
        while ((curJob = jobQueue.pop()) !== undefined) {
            curJob();
            console.log( executed );
        }
    };
    
    // Lets add a Job
    add( function(){ console.log( jobTitle ); } );
    
    execute();
    

    JS Bin

    如您所见,添加的作业可以访问在全局范围内声明的变量 jobTitle。

    希望对你有帮助

    【讨论】:

    • 感谢您的回答,但我不想编辑我网站上的所有脚本我只是将所有内联附属脚本包装在函数中以在不同时间运行它们(在用户接受隐私政策后) ....我知道我可以手动声明全局范围内需要的所有变量,但这会太费力,因为我们正在运行由一些外部模块呈现的多个附属脚本(我们正在运行一个 magento 网上商店)......我需要如果我想以不同的方式声明变量,请编辑所有模块
    • 如果您需要访问在其他地方的函数中声明的变量,您需要将它们存储在共享范围内。使用 iife 的目的是防止全局定义。您可以做的是在全局空间中声明一个对象并将所有变量存储在那里。这就是 jQuery 使用 $() 所做的
    猜你喜欢
    • 2017-01-20
    • 2012-09-08
    • 1970-01-01
    • 2012-03-09
    • 2012-02-18
    • 1970-01-01
    • 2011-03-17
    • 2011-06-07
    • 2015-03-22
    相关资源
    最近更新 更多