介绍JavaScript中的四个陷阱

介绍JavaScript中的四个陷阱。

1. 动态类型

   JavaScript是一种松散类型的语言。换句话说,不需要提前声明存在变量中的数据是什么类型。Java(与JavaScript完全不一样)等其他语言都要求提前声明变量类型,比如 int、float、boolean或String

   //在Java中声明变量

   int number = 5;

   float value = 12.3564;

   boolean active = true;

   String text = "hello";

而JavaScript则会根据赋给变量的数据,自动推断类型。(注意,''或""表示字符串。双引号或单引号都可以表示字符串)

   //在JavaScript中声明变量

   var number = 5;

   var value = 12.3564;

   var active = true;

   var text = "hello";

好讨厌,怎么那么多var!不过有方便的地方:不知道保存什么数据,就可以声明和命名变量。甚至可以随意改变保存的数据类型,JavaScript也不会怪你的:

   var value = 100;

   value = 99.9999;

   value = false;

   value = "hello";

这里需要提醒的是,如果不小心在一个数值变量里存了一个字符串,后来代码就出现了一些奇怪的问题,时候就需要好好反省下。如果不确定某个变量中保存着什么类型的数据,可以使用typeof操作符:

   typeof 67;    //返回"number"

   var myName = "hello";

   typeof myName;   //返回 "string"

2. 变量提升

   在我们的印象中,浏览器会从上到下依次执行JavaScript代码。但是有时候一定!比如,下面这些代码,你觉得变量i什么时候会有定义?

   var numLoops = 100;

   for(var i = 0 ; i < numLoops ; i ++){

       console.log(i);

   }

在其他的很多语言中,i会到for循环开始的时候才会被声明,这符合我们的预期。但是由于存在一种叫做变量提升的机制,JavaScript中的变量声明会被提升到函数上下文的顶部。对于前面的例子来说,i实际上在for循环开始之前就有定义了。下面的代码上面的代码是等价的。

   

   var numLoops = 100;

   var i;

   for(i = 0 ; i < numLoops ; i ++){

       console.log(i);

   }

如果变量名字有冲突,变量提升可能会带来问题。因为你本以为某个变量到后面才会有定义,不成想它早在代码一开始执行时就有定义了。
3. 函数作用域
    在编程领域,变量作用域这个概念用于区分在哪个环境下可以访问那些变量。一般来说,在任何地方都能访问任何值是不正确的。因为这样发生冲突的可能性太高,或者不知道在哪里意外改变了某个值,都会让你着急疯掉。    
    很多语言都有块级作用域,也就是在当前“块”中,变量才有意义。这里的“块”,通常都是花括号。在块级作用域下,前面例子中的变量i只能存在于for循环中,如果想在循环外部读取或者修改i的值,都会失败。这样其实挺好,因为你知道循环中的变量不会跟外部的其他变量有冲突。
    但是JavaScript中的变量只能限制在函数中,即在函数(而不是任何块)中声明的变量只能在函数内部访问。
假如你使用其他语言,那么对这一点也必须格外注意。关键要记住:要想封闭某个值,就得把他们放到函数里。
4. 全局命名空间
 说到变量冲突,我们可以打开网页,调出JavaScript控制台,输入window,然后单击灰色三角,看看里面的内同
像是进入了迷宫一样,这就是所谓的“全局命名空间”
window在浏览器中是一个顶级对象,包含所有的JavaScript中能直接访问到的对象。我们看到的所有的这些对象和值都包含在全局作用域中。换句话说,如果每次都能在全局作用域中声明新变量,那么这个变量就会被加到window对象下面,正像一些JavaScript界敢于仗义执言的人所说,“这是在污染全局命名空间”。
比如,我们在控制台输入:var zebras = "amazing".
然后,再输入window,点开灰色小三角,一直向下滚动,最底部,就可以看到zebras这个变量。
(让人不解的是:在JavaScript中不使用标准的var 也可以定义新变量。因此,只要输入zebra=“amazing”也会看到与前面相同的结果)
给window增加几个值有什么大问题吗?刚开始的时候,啥事也没有。但是随着你的项目越来越复杂,特别是在需要联合使用其他代码(如jQuery、Facebook的like按钮,或者谷歌的分析跟踪代码),说不定就会发生命名冲突。比如,你的项目中使用了变量zebras,而其他的项目中也有这个变量,结果肯定一团糟。至少一些不太规范的数据,可能导致你的项目代码发生错误。
解决这个问题有两个简单的办法:
1)只在函数里面声明变量。虽然有时候也不是绝对可行,但是函数作用域可以防止其他本地变量跟其他变量发生冲突。
2)只声明一个全局对象,然后把你本来想为全家变量的值都作为整个对象的属性。
比如:
    var Vis={};//声明空的全局对象
    vis.zebras = "still pretty amazing";
    vis.monkeys = "too funny LOL";
    vis.fish = "you know, not bad";
这样,所有的变量都被关在笼子里了。(在这里就是全局对象vis里)因此不会再污染全局命名空间。当然,不一定非得叫vis。叫什么都随便,但是太长的话,输入就会很麻烦。无论如何,如果在发生冲突,那肯定是其他脚本也恰好有一个全家对象,而且也有了相同的名字(vis)。但是这种事概率低多了。
参考自《数据可视化实战》
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值