警告:正如此处其他人所述,此问题是基于不灵活的客户要求。虽然问题是正确的,但如果可能的话,您绝对应该使用更简单的解决方案(例如:将设置放在单个对象中)!
我有一个要“注意”的变量数组。那就是:如果它们以前是在代码中定义的,那么我需要能够对它们的值进行操作。
var a = 'foo'; // only a gets defined
// ...more code here... IMPORTANT: I can only control what comes BELOW this line!
var target = 'exmple.com/?';
var gets = ['a', 'b', 'c']; // these are the names of the variables I want to check for
gets.forEach(function(element) { // checking each one
if(typeof element !== 'undefined') { // if it's previously defined
target += "&"+element+"="+eval(element); // add `&a=foo` to target
}
});
alert(target);
我希望警报显示为example.com/?&a=foo
我已经看到大量其他答案,其中包括不使用eval
函数的情况,而且我已经尝试了window[element]
的使用,但没有成功。不必为我要检查的每个变量都编写if / else,最好怎么做?
答案 0 :(得分:1)
假设您不能做其他事情,并且一切都在全局范围内,则可以不使用eval()
而做。 (我很确定eval
必须有一些有效的用例,但我不认为这是其中之一。)
由于您不应该信任这些变量的内容,因此不应该使用eval
。如果您的客户选择受到影响怎么办? (或者仅仅是您的客户不知道他们在做什么。)
var css_color = 'tweet(document.cookie)';
您可以简单地利用以下事实:可以从全局范围访问变量:
const serialize_options = (...vars) =>
vars
.filter(v => typeof this[v] !== 'undefined')
.map(v => `${v}=${this[v]}`)
.join('&');
console.log(serialize_options('a'));
console.log(serialize_options('a', 'b'));
console.log(serialize_options('a', 'b', 'c'));
console.log(serialize_options('a', 'x', 'y'));
<script>
var a = '10';
var b = '20';
var c = '30';
</script>
答案 1 :(得分:0)
这种问题的答案几乎总是“您正在考虑问题错了。”,例如这里。
您假设应该使用变量来完成此操作,这使您陷入只能使用eval()
才能摆脱困境的困境。我了解客户可能要求提供常规变量,但是如果我是房屋建筑商,并且客户要求我用棉花糖盖房子,我会说“不”,那不是这样做的方法。>
解决方案是从一开始就使用带有键和值的对象,这使您以后可以使用数组索引语法,而不是eval
。
// Keep the items you need to check in an object
var obj = {
a:'foo' // only a gets defined
}
var target = 'exmple.com/?';
var gets = ['a', 'b', 'c'];
// Check each array element
gets.forEach(function(element) {
// Objects can use array indexing syntax where a string is passed as the index
// because objects actually have keys, rather than numeric indexes
if(obj[element]) { // if it's previously defined
target += "&" + element + "=" + obj[element]; // add `&a=foo` to target
}
});
alert(target);