如何从动态属性调用和 Uncaught ReferenceError 中删除 eval()

发布于 2024-10-19 08:22:28 字数 1323 浏览 2 评论 0原文

我正在尝试动态调用对象属性。我已经用 eval() 解决了这个问题,但我知道 eval 是邪恶的,我想以更好、更安全的方式做到这一点。我的评估代码:

            // onfocus
            var classes = this.getAttribute('class').split(' ');
            for(var i = 0; i < classes.length; ++i) {
                if(classes[i].match(/val\- */) !== null) {
                    var rule = classes[i].substr(4);
                    var instruction = eval('validate.instructionTexts.'+ rule +'()');

                    tooltip.appendChild( document.createTextNode(instruction) );
                }
            } 

我也有这个代码:

       // onblur
        var classes = this.getAttribute('class').split(' ');
        for( var i = 0; i < classes.length; ++i ){
            if(classes[i].match(/val\- */) !== null) {
                var rule = classes[ i ].substr( 4 );
                var tooltip = document.getElementsByClassName( 'tooltip' );
                for( i = 0; i < tooltip.length; ++i){
                    tooltip[ i ].style.display = 'none';
                }

                eval('validate.rules.'+ rule +'(' + (this.value) + ')');
            }

第二个代码的问题是我想向我的属性发送一个字符串。 this.value = 我在文本框中输入的文本,因此我从 this.value 中获得了正确的字符串,但出现了此错误。

如果我输入 foo. 未捕获的引用错误:foo 未定义。 Javascript 认为我试图发送一个变量,但我希望它发送一个字符串。我该如何解决这个问题?

I'm trying to call object properties dynamically. I have solved the problem with eval() but i know that eval is evil and i want to do this on a better and safer way. My eval code:

            // onfocus
            var classes = this.getAttribute('class').split(' ');
            for(var i = 0; i < classes.length; ++i) {
                if(classes[i].match(/val\- */) !== null) {
                    var rule = classes[i].substr(4);
                    var instruction = eval('validate.instructionTexts.'+ rule +'()');

                    tooltip.appendChild( document.createTextNode(instruction) );
                }
            } 

And I also have this code:

       // onblur
        var classes = this.getAttribute('class').split(' ');
        for( var i = 0; i < classes.length; ++i ){
            if(classes[i].match(/val\- */) !== null) {
                var rule = classes[ i ].substr( 4 );
                var tooltip = document.getElementsByClassName( 'tooltip' );
                for( i = 0; i < tooltip.length; ++i){
                    tooltip[ i ].style.display = 'none';
                }

                eval('validate.rules.'+ rule +'(' + (this.value) + ')');
            }

the problem with the second code is that I want to send a string to my property. this.value = the text i type in my textbox so i get correct string from this.value but i got this error.

if i type foo.
Uncaught ReferenceError: foo is not defined. Javascript thinks I trying to send a variabel but i want it to send a string. How can i solve this problems?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

绿光 2024-10-26 08:22:28
  1. HTML 元素的 CSS 类可以通过 className 属性直接从 JS 访问。
  2. JS 对象属性可以通过点符号 object.property 或通过方括号符号 object['property'] 访问。
  3. 正则表达式 /val\- */ 匹配字符串中任意位置的字符 v、a、l、“-”连字符以及零个或多个空格。
    • 空格完全无关,因为您正在测试按空格分割的字符串的结果(因此它不再包含任何空格)。
    • 此外,您没有锚定正则表达式,因此一类'eval- test' 也将被匹配。我怀疑这就是您要找的东西。
    • 如果您只是测试以 val- 开头的类,那么 indexOf 方法更容易阅读,而且可能也更高效。

我已经相应地调整了你的代码。我假设验证规则的类名均以 val- 开头,类名的其余部分是规则的名称:

// onfocus
var classes = this.className.split(' ');
for(var i = 0; i < classes.length; ++i) {
    if(classes[i].indexOf('val-') === 0) { // the class name starts with 'val-'
        var rule = classes[i].substr(4);
        var instruction = validate.instructionTexts[rule]();

        tooltip.appendChild(document.createTextNode(instruction));
    }
}


// onblur
var classes = this.className.split(' ');
for (var i = 0; i < classes.length; ++i ){
    if(classes[i].indexOf('val-') === 0) { // the class name starts with 'val-'
        var rule = classes[i].substr(4);
        var tooltip = document.getElementsByClassName('tooltip');
        for (i = 0; i < tooltip.length; ++i){
            tooltip[i].style.display = 'none';
        }

        validate.rules[rule](this.value);
    }
}
  1. An HTML element's CSS class can be accessed directly from JS thru the className property.
  2. JS object properties can be accessed via the dot-notation object.property or via the square-bracket-notation object['property'].
  3. The regex /val\- */ matches the characters v, a, l, a '-' hyphen, and zero or more spaces, anywhere in the string.
    • The spaces are completely irrelevant since you're testing the result of a string that was split on spaces (and so it won't contain any spaces anymore).
    • Also, you're not anchoring the regex so a class of 'eval-test' will also be matched. I doubt that's what you're looking for.
    • If you were just testing for the classes starting with val-, then the indexOf method is much easier to read, and probably also a lot more efficient.

I've adjusted your bits of code accordingly. I'm assuming that the class names for your validation rules all start with val-, and that the rest of the class name is the name for the rule:

// onfocus
var classes = this.className.split(' ');
for(var i = 0; i < classes.length; ++i) {
    if(classes[i].indexOf('val-') === 0) { // the class name starts with 'val-'
        var rule = classes[i].substr(4);
        var instruction = validate.instructionTexts[rule]();

        tooltip.appendChild(document.createTextNode(instruction));
    }
}


// onblur
var classes = this.className.split(' ');
for (var i = 0; i < classes.length; ++i ){
    if(classes[i].indexOf('val-') === 0) { // the class name starts with 'val-'
        var rule = classes[i].substr(4);
        var tooltip = document.getElementsByClassName('tooltip');
        for (i = 0; i < tooltip.length; ++i){
            tooltip[i].style.display = 'none';
        }

        validate.rules[rule](this.value);
    }
}
轮廓§ 2024-10-26 08:22:28

您不需要使用 eval,您可以通过以下方式访问它:

validate.rules[rule](this.value);

这也将解决您的其他问题,即您传入 this.value 的值,当 eval()'d 时没有被引用为字符串('foo' 是),因此被解释为变量。

You do not need to use eval, you can access it as:

validate.rules[rule](this.value);

Which will solve your other problem too, which is that you are passing in the value of this.value which when eval()'d is not quoted as a string (which 'foo' is) so is being interpreted as a variable.

甜是你 2024-10-26 08:22:28

要从对象 obj 获取属性 foo,您可以使用

obj.foo

obj["foo"]

第一个不允许保留字或者属性包含空格。

所以你的第一个例子可以改为

validate.instructionTexts[rule]()

to get a property foo from object obj, you could use either

obj.foo

or

obj["foo"]

The first one won't allow reserved words or if the property contains spaces.

So your first example could change to

validate.instructionTexts[rule]()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文