本篇适合javascript新手或者学了前端一段时间,对js概念不清晰的同学~~。
学习目的
本文针对javascript基础薄弱的同学,可以加深对javascript的理解。
本文将讲述以下几点对于初学者开说javascript(有的是大部分语言都有的)的坑
讲解内容如下:
1. 连等
2. i++
3. 包装对象
4. 引用类型
5. && 与 ||
讲解部分
1. 连等
小试牛刀
连等是常见的表达式,但是并不是所有情况都适合连等,连等只适用于字面量并不适用于引用类型。
// 字面量连等得到想要的结果var a,b;a = b = 2;a // 2b // 2// 引用类型连等不可预测var arr1, arr2;arr1 = arr2 = []arr1[0] = 10arr2[0] // 10//引用类型连等使得两个引用指向一个对象,操作其中一个,两个值都变
以上代码是常见的连等,有时候我们需要两个变量同赋值为一个值,我们就这样来操作,但是,如果是引用类型可不能连等赋值哦。
此外,连等赋值会有一个很大的漏洞,就是会将变量泄露到全局中去,上面代码我们没有将其泄露,但看下面代码:
function fn (num) { var a = b = num; a // num b // num}fn(10)a // 报错b // 10// 我们并不没有定义全局变量b
可以看到,我们执行了fn函数后,全局作用域中出现了b变量,这是为什么?看 var a = b = num这句话,这句话可以分成两句来看
var aa = b = num//只声明了a
我们其实只声明了a变量,连等的b并没有声明,由此可以知道,b被挂在了全局的window对象上,造成了变量泄露到了全局。
初出茅庐
上面只是简单的例子,接下来我们看一个复杂点的例子
var a = {x: 1}var b = aa.x = a = {y: 1}a.x // undefinedb.x // {y: 1}
这个例子是在一个测试题中看到的,乍一看,好像不明觉厉,但是一点都不难理解。
1. a 和 b是引用了类型,同指向了一个对象 {x: 1}
2. a.x 引用了原对象的x属性, a 则为一个引用变量
3. a = {y: 1} 只是将a这个引用变量的指针指向了另一个对象{y: 1}
4. a.x = a,前者还是代表着原来的对象的x属性,也就是b引用的对象的x属性
5. 赋值完毕。
可能你还没有理解,不要急,下面我们将解剖javascript引擎让你懂的明明白白
庖丁解牛
引擎的工作原理: 引擎在解析javascript表达式时,会进行LHS查询, RHS查询(详见《你不知道的javascript》),我将它们理解为LHS(赋值),RHS(查找)。
下面,就上面例子,我们来演示一下引擎的工作流程
var a = {x: 1}// 引擎:我将要对a变量LHS(赋值),内容是{x: 1}// 作用域: 刚声明了a变量,给你。var b = a// 引擎: 我将要对a变量RHS(查找)// 作用域: 你刚刚给它LHS了,给你吧// 引擎: 我将要对b变量LHS(赋值),内容为a变量指向的对象// 作用域:刚声明了b变量,给你。a.x = a = {y: 1}// 引擎:我将要对a进行LHS(赋值),内容是另一个对象{y:1}// 作用域:可以,给你,但好像还有其他命令,先不要赋值。// 引擎: 是的,下一步我还需要对a.x 进行LHS(赋值),内容是将要改变的a变量// 作用域: 可以,a变量指向的对象有x属性,不过马上a就改变了,不过没关系,b变量也指向那个对象,赋值完后,你可以用b变量引用旧对象。// 引擎:了解了,我先把a变量赋值为一个新的对象,然后把原来的a变量指向的对象的x属性赋值为 新a。a.x // undefined// 引擎: 我需要拿到a变量指向的对象的x属性// 作用域: 你刚刚改变了a的指向,现在的a指向的对象已经没有x属性了b.x // {y: 1}// 引擎: 我需要拿到b变量指向的对象的x属性// 作用域: 你是想拿到你旧对象的x属性吧,给你,不过已经被你在之前改变了值,现在b.x的值就是a指向的新对象的值。
新闻热点
疑难解答
图片精选