《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之间的差别
- eval()会影响到作用域
- new Function()中的代码将在局部函数空间中运行,因此代码中任何采用var定义的变量不会自动成为全局变量
- 无论在哪里执行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' })();
github博客:https://github.com/chyingp/blog
新浪微博:http://weibo.com/chyingp
站酷主页:http://www.zcool.com.cn/u/346408/