PHP群:95885625 Hbuilder+MUI群:81989597 站长QQ:634381967
    您现在的位置: 首页 > 开发编程 > 编程杂谈 > 正文

    JavaScript语法陷阱

    作者:admin来源:网络浏览:时间:2020-09-30 00:07:50我要评论
    导读:没有一种编程语言是完美的,JavaScript 也不例外,它的语法陷阱重重,防不胜防:加号with分号自动插入声明提升eval多行字符串变量泄漏argu
    1. 难判断它究竟要做啥,即使那是你自己几天前写的。
    2. JavaScript 解释器引擎难以对代码执行优化。
    3. 如果 eval 中的字符串包含用户输入的数据,这会给攻击者有机可乘。
    4. 如果你是有经验的开发者,大多数情况下你可以使用更高效的函数嵌套(闭包)等来解决问题;如果你没有足够的经验,那更不要使用 eval ,如果你不想你或你的用户遭受攻击。

    多行字符串

    JavaScript 中不能直接书写多行的字符串,需要在行尾输入一个反斜杠 \

    假设我们的项目中有一段这样的代码:

    var multiStr = "this is a multi-line string, \
    and this is the second line. \
    yes, the string ends here";

    然后做了一些维护和更新:

    var multiStr = "this is a multi-line string, \
    and this is the second line. \ 
    now i want to insert a line right here, \
    yes, the string ends here";

    凭肉眼似乎没看出毛病,但运行时却得到了一个语法错误,这之前你可能已经注意到语法高亮已经失效了。几经周折,你终于注意到了第2行行尾的那个不起眼的空格。。

    变量泄漏

    JavaScript 的全局作用域给了我们很多便利,有时我们无需使用 var 来声明变量。

    很多 JavaScript 的入门开发者,喜欢利用这个“便利”。但事实上它是一个陷阱。它很可能让我们的一些敲打错误被隐藏和掩盖。

    function foo() {
        var type = "first";
        if (something) {
            // 这里假设我们手一抖,把type打成了typo
            typo = "second";
        }
        return type;
    }

    这段代码可以让项目长久地稳定运行,但随后的某天,我们吃惊地发现,所有的 type 都是 “first” !在找到并修复这个手误之前,我们以此得到的数据或结论可能都要被废弃。

    直接使用没有声明的变量,将自动创建一个全局变量,滥用会导致全局变量污染,或者让类似上面这样的手误逍遥法外。合理的声明变量,并利用作用域链与闭包,是 JavaScript 解决很多问题的思路。

    “arguments.callee”

    写一个递归函数,我们通常这样:

    function factorial(n) {
        return n <= 1 ? 1 : factorial(n - 1) * n;
    }
    [1, 2, 3, 4, 5].map(factorial);

    有时我们不想污染命名空间,需要递归调用一个匿名函数,怎么办?

    [1, 2, 3, 4, 5].map(function(n) {
        return n <= 1 ? 1 : /* what goes here? */ (n - 1) * n;
    });

    还好我们有 arguments.callee

    [1, 2, 3, 4, 5].map(function(n) {
        return n <= 1 ? 1 : arguments.callee(n - 1) * n;
    });

    但是同样不推荐使用 arguments.callee :

    1. 访问 arguments.callee 的开销是昂贵的。
    2. 使用它将导致 JavaScript 解释器难以执行优化。
    3. 从 ECMAScript 3 开始,已经支持命名函数表达式

    命名函数表达式:

    [1, 2, 3, 4, 5].map(function factorial(n) {
        return n <= 1 ? 1 : factorial(n - 1) * n;
    });

    注意,这里的函数 factorial() 并不是函数声明,而是命名函数表达式,factorial 所处的作用域是其函数本身的作用域(与参数 n 属同一个作用域),而不是当前的全局作用域。但是,在 IE8 及以下浏览器中,情况则不同,它将属于全局作用域。

    转载请注明(B5教程网)原文链接:https://b5.mxunkeji.com/content-74-128-1.html
    相关热词搜索: 语法陷阱