如何在两行代码之间检测运行时添加的全局变量?

时间:2016-11-20 11:55:59

标签: javascript

如何在两行代码之间检测运行时添加的全局变量?

我希望能够在运行时分析两行代码中添加的变量,而无需分析源代码。只添加了1个变量。

示例:

"use strict";
//start

const myVariable = "10"; //detect this new variable

//end

const newVariableAdded = detectWhatIsNew();

// newVariableAdded should be "10" or "myVariable"

到目前为止我尝试了什么:

"use strict";

const notNew = Object.getOwnPropertyNames(window);

const detectWhatIsNew = function () {
    let newString;

    let key;
    Object.getOwnPropertyNames(window).some(function (key) {
        if (!notNew.includes(key)) {
            notNew.push(key);
            newString = key;
            return true;
        }
    });
    return newString;
};


//start    

const myVariable = "10"; //detect this new variable

//end

const newVariableAdded = detectWhatIsNew();

// newVariableAdded should be "10" or "myVariable"

3 个答案:

答案 0 :(得分:0)

constlet是块范围的,它们不会在全局对象上创建属性,但是您的环境中运行的所有代码都可以访问它们(如果在外部声明的话)一个块,在顶层)。

您的代码仅适用于var或者您不使用任何声明。

我不认为有一些方法可以做你想做的事。

答案 1 :(得分:0)

@EdmundoRodrigues所说的几乎是正确的,除了它适用于var(在这种情况下它不会,但它适用于不存在的全局属性赋值...“set”,独立于{{1 }}

您无法检测到undefined添加变量(使用var声明)的情况,因为var语句会立即声明变量(抱歉,如果我的条款没有' t fit,英语不是我的主要语言),例如:

var

(_ => { a = "10" var a alert(self.a) // undefined on window (global object) // So the variable a can be assigned and used before the var // keyword comes. // If var [a] were not declared here, a would be global, or // if it was strict mode, an exception would have been // thrown. }) () 就是这样,varlet除外:

const

您的函数将只计算在下一个单独的脚本中使用的全局( _ => { a = "10" // Uncaught ReferenceError: a is not defined(…) let a })() 语句,并且还将计算当前正在执行的表达式/语句中先前不存在的任何全局对象属性,而不管var值。

undefined不同,

constlet只会在整个范围内显示,直到执行声明为止。正如@EdmundoRodrigues所说,varlet变量只在本地可见,与范围无关(即使范围是全局的)。

#检查您的代码(注意:我对const进行了更改以返回所有最近的变量,并使用detectWhatIsNew声明myVariable。)

var

这对"use strict" const detectWhatIsNew = _ => Object.getOwnPropertyNames(self).filter(key => !notNew.includes(key) && notNew.push(key)) const notNew = Object.getOwnPropertyNames(self) var myVariable console.log(detectWhatIsNew()) // an empty array 无效,但确实有意义!由于var的存在是即时的,var调用会在任何位置捕获此Object.getOwnPropertyNames(self)

"a"

但是你的功能仍然适用于设置全局变量的不同方式,例如:

console.log(notNew.indexOf( "myVariable")) // bigger than -1

答案 2 :(得分:0)

一种方法是使用var语句并将代码拆分为多个文件,以便var语句不会被提升。可以使用服务工作者自动拆分文件。

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>Title</title>
</head>
<body>

<script src="prepare.js"></script>
<script src="addVariable.js"></script>
<script src="detectNewVariable.js"></script>
</body>
</html>

prepare.js

"use strict";

const notNew = Object.getOwnPropertyNames(self);

const detectWhatIsNew = _ => {3
    /*returns an array*/
    return Object.getOwnPropertyNames(self).filter(key => {
        if (!notNew.includes(key)) {
            notNew.push(key)
            return true
        }
    });
};

addVariable.js

var myVariable = "10";

detectNewVariable.js

console.log(detectWhatIsNew()); // Array [ "myVariable" ]

另一种方法是使用window.variable =表示法

创建全局变量