《javascript模式》 容易踩中的那些坑

简介:

  

1 链式赋值的陷阱

   1:  function func(){
   2:      var innerVar = globalVar = 20;    
   3:  }
   4:  func();
   5:  console.log(typeof globalVar);    //输出结果为?

 

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

真相是:number

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

var a = (b = 0);

 

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

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

 

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的陷阱

   1:  function func(){
   2:      var innerVar = globalVar = 20;    
   3:  }
   4:  func();
   5:  console.log(typeof globalVar);    //输出结果为?

 

将上述代码稍微修改下又如何呢?
   1:  var person = {
   2:      name: 'casper',
   3:      age: 11
   4:  };
   5:  Object.prototype.getName = function(){};  
   6:  for(var key in person){
   7:      console.log(key);
   8:  }

输出结果变成:

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

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

 

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

  1. eval()会影响到作用域
  2. new Function()中的代码将在局部函数空间中运行,因此代码中任何采用var定义的变量不会自动成为全局变量
  3. 无论在哪里执行Function,它都仅能看到全局作用域
   1:  console.log(typeof un);  //'undefined'
   2:  console.log(typeof deux);  //'undefined'
   3:  console.log(typeof trois);  //'undefined'
   4:   
   5:  var jsstring = "var un  = 1; console.log(un);";
   6:  eval(jsstring);  //logs "1"
   7:   
   8:  jsstring = "var deux = 2; console.log(deux);";
   9:  new Function(jstring)();  //logs "2"
  10:   
  11:  jsstring = "var trois = 3; console.log(trois);";
  12:  (function(){
  13:      eval(jsstring);
  14:  })();  //logs  "3"
  15:   
  16:  console.log(un);  //'number'
  17:  console.log(typeof deux);  //'number'
  18:  console.log(typeof trois);  //'undefined'

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

 

   1:  (function(){
   2:      var local = 1;
   3:      eval("local = 2; console.log(local);");  //logs 3
   4:      console.log(local);  //logs 3
   5:  })();
   6:   
   7:  (function(){
   8:      var local = 1;
   9:      new Function("console.log(typeof local);")();  //logs 'undefined'
  10:  })();


 


本文转自艾伦 Aaron博客园博客,原文链接:http://www.cnblogs.com/aaronjs/p/3164261.html,如需转载请自行联系原作者

相关文章
|
6月前
|
设计模式 缓存 JavaScript
JavaScript 简单实现观察者模式和发布-订阅模式
JavaScript 简单实现观察者模式和发布-订阅模式
32 0
|
4月前
|
前端开发 JavaScript
JavaScript基础知识:JavaScript 中的异步编程有哪些模式?
JavaScript基础知识:JavaScript 中的异步编程有哪些模式?
37 0
|
9月前
|
设计模式 前端开发 JavaScript
|
9月前
|
设计模式 前端开发 JavaScript
|
9月前
|
JavaScript
【常见面试题】JS 发布者、订阅者模式
面试中经常出现问到如何实现JS 发布者、订阅者模式。
76 2
【常见面试题】JS 发布者、订阅者模式
|
5月前
|
JavaScript 程序员 Go
一图看懂编程语言迁移模式:终点站是Python、Go、JS
一图看懂编程语言迁移模式:终点站是Python、Go、JS
|
5月前
|
存储 前端开发 JavaScript
如何使用CSS和JavaScript实施暗模式?
如何使用CSS和JavaScript实施暗模式?
|
6月前
|
移动开发 JavaScript
同样的JS效果,有部分页面生效,有部分页面无效的原因(怪异模式)
同样的JS效果,有部分页面生效,有部分页面无效的原因(怪异模式)
30 0
|
8月前
|
设计模式 开发框架 JavaScript
理解JavaScript 的发布者_订阅者模式
理解JavaScript 的发布者_订阅者模式
47 0
|
9月前
|
存储 设计模式 前端开发