zoukankan      html  css  js  c++  java
  • 《javascript模式》读书笔记:容易踩中的那些坑

    《javascript模式》第2章 基本技巧 中,讲了一些在前段编程中的一些规范和建议,同时还有一些平常经常忽视且容易踩中的坑。

    以下仅是部分内容的摘要和总结,以做备忘用,如有错漏,敬请指出。如需了解更多,可参阅原著,挺不错的书。

    1 链式赋值的陷阱

    function func(){
        var innerVar = globalVar = 20;    
    }
    func();
    console.log(typeof globalVar);    //输出结果为?

    上面最后的输出结果是?相信不少人会毫不犹豫地说undefined,确定?

    真相是:number

    原因:从右至左操作符的优先级。首先,优先级较高的是表达式b=0,此时b未经声明。表达式的返回值为0,它被赋给var声明的局部变量a,如以下代码所示

    var a = (b = 0);

    建议:对链式赋值的所以变量都进行声明,再进行赋值

    function foo() {
        var a, b;
        a = b = 20;    //都是局部变量
    }

     

    2 变量释放时的副作用

    隐含全局变量与明确定义的全局变量有细微的不同,不同之处在于能否使用delete操作符撤销变量

    • 使用var创建的全局变量(这类变量在函数外部创建),不能删除
    • 不使用var创建的隐含全局变量(尽管它是在函数内部创建),可以删除

    这表明隐含全局变量严格来讲不是真正的变量,而是全局对象的属性。属性可以通过delete操作符删除,但变量不可以

    //定义三个全局变量
    var global_var = 1;
    global_novar = 2;  //反模式
    (function(){
        global_fromfunc = 3;  //反模式
    })();
    
    //企图删除
    delete global_var;  //false
    delete global_novar;  //true
    delete global_fromfunc;  //true
    
    //测试删除情况
    typeof global_var;  //'number'
    typeof global_novar;  //'undefined'
    typeof global_fromfunc;  //'undefined'

    在ES5 strict模式中,为没有声明的变量赋值会抛出错误

     

    3 for-in的陷阱

    var person = {
        name: 'casper',
        age: 11
    };
    for(var key in person){
        console.log(key);
    }

    运行下上述代码,毫无意外,输出结果为:

    输出:name输出:age

    将上述代码稍微修改下又如何呢?

    var person = {
        name: 'casper',
        age: 11
    };
    Object.prototype.getName = function(){};  
    for(var key in person){
        console.log(key);
    }

    输出结果变成:

    输出:name输出:age输出:getName

    建议:不要增加内置对象的原型,除非必要,同时需在团队内进行良好的沟通,确保其他团队成员不会因此而遇到一些奇怪的错误

     

    4 注意eval与new Function之间的差别

    1. eval()会影响到作用域
    2. new Function()中的代码将在局部函数空间中运行,因此代码中任何采用var定义的变量不会自动成为全局变量
    3. 无论在哪里执行Function,它都仅能看到全局作用域

    直接看代码示例:

    console.log(typeof un);  //'undefined'
    console.log(typeof deux);  //'undefined'
    console.log(typeof trois);  //'undefined'
    
    var jsstring = "var un  = 1; console.log(un);";
    eval(jsstring);  //logs "1"
    
    jsstring = "var deux = 2; console.log(deux);";
    new Function(jstring)();  //logs "2"
    
    jsstring = "var trois = 3; console.log(trois);";
    (function(){
        eval(jsstring);
    })();  //logs  "3"
    
    console.log(un);  //'number'
    console.log(typeof deux);  //'number'
    console.log(typeof trois);  //'undefined'

    从上面代码示例可以很清楚地看出前两点,关于第三点,请看下面代码示例:

    (function(){
        var local = 1;
        eval("local = 2; console.log(local);");  //logs 3
        console.log(local);  //logs 3
    })();
    
    (function(){
        var local = 1;
        new Function("console.log(typeof local);")();  //logs 'undefined'
    })();
  • 相关阅读:
    Windows API 中 OVERLAPPED 结构体 初始化
    QString 转换成 wchar 的一个小陷阱
    Windows VHD Create, Attach, 获得Disk序号
    Programmatically mount a Microsoft Virtual Hard Drive (VHD)
    chcp437 转换英语,在西班牙语系统中无效
    Windows 版本 Enterprise、Ultimate、Home、Professional
    openssl 查看证书
    Ubuntu 搜索文件
    微软的 Sysinternals 系统管理工具包,例如可找出自动启动的流氓软件
    HTML 表格实例
  • 原文地址:https://www.cnblogs.com/chyingp/p/2711417.html
Copyright © 2011-2022 走看看