走进javascript——不起眼的基础,值和分号
值
有时我很想知道javascript解析引擎是如何区分一个变量的值,比如下面这段代码。
var x = 'javascript'; //javascript
x = "hello"; // hello
x = 555; //555
x = null; //null
x = a; //a is not defined
x = true; //true
对于数字是直接赋值的,因为它没有多样性,数字就是数字。但是对于值是英文的情况就很难区分了,因为在编程语言中,英文既可能是字符串,也可能是引用的另外一个变量。因此如何区分变量和字符串就显得格外重要,编程语言常常将字符串用引号括起来,从而达到区分变量和字符串的作用。有些语言比如java,它们还区分单引号和双引号,单引号括起来的是一个字符,而双引号括起来的才是字符串。但javascript并不区分字符和字符串,而是把它们都当作字符串,因此在javascript中单引号和双引号并没有什么区别。
虽然通过引号可以用来区分变量和字符串,但值往往也可能是一个关键字,比如上面那段代码我将x赋值为null,那么这些编程语言又是如何区分变量和关键字的呢?
null = 123;
console.log(null); //Uncaught ReferenceError: Invalid left-hand side in assignment
undefined = 456;
console.log(undefined); //undefined
以上我给null和undefined分别赋给了另外一个值,其结果,给null赋值报错了,给undefined赋值虽然没有报错,但也没有成功。也许对于null和undefined来说,它们就是值。而变量则是寻找值。我们说javascript是如何区分变量和关键字,最终或许就变成了javascript是如何区分变量和值的。
分号
在一些JS插件中,经常会看到类似下面这样的一行代码
;(function(){
.........
})();
在代码的最前面有一个分号,那么这个分号是干什么用的呢?
我们知道一个分号代表了一段代码的结束,但问题是javascript允许你不写分号,这样就出现了一个问题,代码的结束与否不是你来决定的而是由程序来决定的,而程序也不是万能的,往往它只是走的某个规则,而如果你写的这段代码和它的规则不符,最终的结果就有些不如人意了。
以下是javascript对省略分号的解析规则
var a
=
1 + 2
console.log(a) //3
javascript解析器会将以上代码解析成
var a = 1 + 2;
console.log(a); //3
如果javascript不给2后面添加分号将会无法解析下去,也可以这么说,如果遇到无法解析下去则javascript解析器会尝试给其添加一个分号,如果还是解析不了则报错。又比如下面这一段代码
var a = 10;
var b = 5;
var c = a + b
(a + b).toString()
// b is not a function
它说b不是一个函数,也就是说以上这段代码很有可能解析成了下面这段代码
var a = 10;
var b = 5;
var c = a + b(a + b).toString();
它把()当成了函数调用。也可以理解为javascript解析器会尽可能多的去匹配,但也有几个例外,它们是retrun、break、continue,当javascript解析器解析到这几个关键字时,它不会把换行后的内容当成是自身的,而是直接在换行之前添加分号,不妨看看下面这段代码
function test(){
return
123;
}
console.log(test()); //undefined
它并没有返回123,也就是说它直接在retrun后面加了分号。
再回过头来看看,那些插件开发者为什么要在代码第一行添加一个分号?
既然是插件,自然是给别人用的对吧,可关键问题是你也不清楚使用这个插件的人它的代码是如何编写的,这好像挺谬论的,它的代码和我们有什么关系呢。
如果说使用者的代码会影响我们的代码,那么它又是如何影响的呢?比如我们正在编写类似下面这样的一段代码
<script src="test.js"></script>
<script src="zmz.js"></script>
第一个脚本是使用者自己写的,第二个脚本是引入的某个插件,那么浏览器又是如何解析这两个脚本的呢?不妨我们来测试一下
test.js
var a
a
zmz.js
(1+2)
如果你运行起来会发现并没有报错,也就是说javascript解析器并不会因为前面这个文件没有加分号而和后一个文件中的代码一起解析。
问题倒不在这,而是有可能你刚刚看了一本关于HTTP的书,哇靠,原来把文件合并可以减少请求数,于是乎这两个脚本融为一体了。摇身一变成了下面这样
var a
a(1+2)
你说这能不出错吗,如果我们在插件的一开始就加上分号,这种事情就不可能出现。
var a
a;(1+2)
因此不要把分号单单认为只是用来结束某段代码,它还可以用来隔离某段代码和别人划清界限。
最新文章
- InnoDB:Lock &; Transaction
- JQuery------日期格式转换
- ExtJs基础知识总结:自定义弹窗和ComboBox自动联想加载(四)
- jQuery Validate验证框架详解
- 如何在脚本中获取进程ID(PID)
- 从零开始系列--R语言基础学习笔记之一 环境搭建
- Qt QT_BEGIN_NAMESPACE
- js—对象
- java版-JQuery上传插件Uploadify使用实例
- js 去重 字符串 [123123,123123,345435,33467,45645,343467,879,45645]
- hdu5172(线段树)
- 什么是Git?
- 使用TCP/IP Monitor监视Soap协议
- OpenStack Paste.ini详解(二)
- tomcat 请求处理流程分析(基于nio)
- 用 Lua 控制 MIDI 合成器来播放自定义格式乐谱
- 机器学习进阶-案例实战-答题卡识别判 1.cv2.getPerspectiveTransform(获得投射变化后的H矩阵) 2.cv2.warpPerspective(H获得变化后的图像) 3.cv2.approxPolyDP(近似轮廓) 4.cv2.threshold(二值变化) 7.cv2.countNonezeros(非零像素点个数)6.cv2.bitwise_and(与判断)
- 用URL传递参数
- 乘风破浪:LeetCode真题_040_Combination Sum II
- 【delphi】多线程与多线程同步
热门文章
- xcode调试
- Java解析JSON文件的方法 (二)
- WebGIS中通过行列号来换算出多种瓦片的URL 之离线地图(转载)
- iOS 错误 之 Potential leak of an object stored into &#39;cs&#39;
- docker mac 安装并初始化GO环境
- js原生设计模式——2面向对象编程之js原生的链式调用
- 【angularjs】【学习心得】路由基础篇
- iOS 之 alcatraz (插件管理器)
- Java线程:同步
- spring mvc在Controller中获取ApplicationContext