javascript基础知识讲解


Posted in Javascript onJanuary 11, 2017

本篇适合javascript新手或者学了前端一段时间,对js概念不清晰的同学~~。

学习目的

本文针对javascript基础薄弱的同学,可以加深对javascript的理解。

本文将讲述以下几点对于初学者开说javascript(有的是大部分语言都有的)的坑

讲解内容如下:

1. 连等

2. i++

3. 包装对象

4. 引用类型

5. && 与 ||

讲解部分

1. 连等

小试牛刀

连等是常见的表达式,但是并不是所有情况都适合连等,连等只适用于字面量并不适用于引用类型

// 字面量连等得到想要的结果
var a,b;
a = b = 2;
a // 2
b // 2
// 引用类型连等不可预测
var arr1, arr2;
arr1 = arr2 = []
arr1[0] = 10
arr2[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 a
a = b = num
//只声明了a

我们其实只声明了a变量,连等的b并没有声明,由此可以知道,b被挂在了全局的window对象上,造成了变量泄露到了全局。

初出茅庐

上面只是简单的例子,接下来我们看一个复杂点的例子

var a = {x: 1}
var b = a
a.x = a = {y: 1}
a.x // undefined
b.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指向的新对象的值。

以上是我的理解,没有权威认证。想详细了解执行过程,请参考《你不知道的javascript》,如果本节有误,请指出。

2. ++操作符

大家最很常用 ++ 操作符,其实也没什么很大奇特之处,但是对于新手入门的你是否真正了解他。

var a = 1;
var b = a++
a // 2
b // 1
var c = 1;
var d = ++ c;
c // 2
d // 2

前++和后++,一个是返回表达式自增后一个是返回表达式自增前的值。我们可以把两个进行分解,看一下过程。

b = a++
// 等价于 ...
b = a
a = a + 1
//.........................
b = ++ a
// 等价于 ...
a = a + 1
b = a

只是一个运算顺序问题,这个可能好理解,但是也有一个坑,如下。

前几天一个人问: 1++ 等于几?答: 2

估计很多人第一反应就是2,但是这大错特错!那为什么不等于2呢,其实 1++是报错了,并不是合法的表达式,原因如下:

1 ++
// 等价于
1 = 1 + 1
// 引擎对 1 进行LHS(赋值),作用域发现他是非法变量,所以会报错 左值无效。

3. 包装对象

我们在用字符串获取长度、使用方法截取等行为时,你有没有想过: 字面值只是个值,为什么他会有方法属性,不是应该对象才有的吗?的确是对象才有的,但是在执行表达式时,产生了包装对象。也许你看过了此知识点,可以跳过。

var str = 'hello'
str.length // 5
str.aaa = 5
str.aaa // undefined

我们定义一个str字符串,获取长度为5,但是我们自己加一个属性aaa缺获取不到,这需要用包装对象的声明周期来解答:包装对象的声明周期只存在于一个表达式内

var str = 'hello'
str.length
// 等价于
new String(str).length
str.aaa = 5
//等价于
new String(str).aaa = 5
str.aaa
// 等价于
new String(str).aaa

也就是说,每一次用到str属性时,都是先包装成String对象,操作完后,对象释放,可见,以上两次str.aaa是不同的对象,所以第二次获取aaa属性当然没有了。不了解可以百度一下js包装对象,有详细的解答。

4. 引用类型

大部分语言都有引用类型,其实就是对象变量。c语言中,我们将引用类型理解为指针,这个指针是动态指向一块内存,通过代码的变化,指针的指向会随之改变。js也一样。

在我们书写代码中,一定要记住引用类型变量和字面值变量的 区别,他们分别有不同的用处。

var global = new Object()
function setColor (obj) {
 obj.color = 'blue'
 obj = new Object()
 obj.color = 'red'
}
setColor(global)
global.color // blue

这是《javascript高级程序设计》里面的一个例子,我们传递一个对象global到setColor函数里,在内部进行了如上操作,我们打印出global.color是blue,为什么不是red?这里就是引用类型的结果。

1. global变量是引用类型,他指向一个对象,

2. 传递到setColor函数中,obj就引用了global指向的对象(下面称为globalObj)

3. 给globalObj赋值一个color属性为blue字符串,这时global.color是blue了

4. 将obj指向另一个新对象localObj,使得obj与global断开连接。

5. 将localObj.color赋值为‘red'

可以看出,我们并没有对global对象的color进行'red'赋值,'red'赋值给了另一个对象的color属性。

结论:引用类型传递是将两个变量指向同一个对象,而字面量的传递仅仅是值的赋值传递。我们可以将引用类型传递到函数进行改变,不可以在函数内改变传递进来的字面值。

5. && 与 ||

两者的基本运用相信大家都了解,大部分用来if判断,如:

var a = 2;
var b = false
if (a && b) {

 alert('best')
}
if (a || b) {
 alret('good')  // 运行
}

他们的用法不局限于判断 左右两边的 && 和 || 关系,还可以用来提供代码的质量

var obj = {}
if (obj.info.user === 'xu') { // terrible
 // ..
}
if (obj.info && obj.info.user === 'xu' ) { // good
 // ... 
}

如果仅仅判断obj.info.user 会报错造成程序终止,但是下面那样判断就大使得代码健壮,不会那么容易崩溃。

重点: && 和 || 并不会返回true和false,他会返回终止此表达式的那个变量值。

true && 6 // 6
NaN && false // NaN
'0' || 6 // '0'
false || true // true
false || 0 && 1 // 0
false || 1 && 0 // 0

&&和||, &&优先级大于||。

&&操作符,如果左边为假,返回左边值,否则,始终返回右边值

||操作符,如果左边为真,返回左边值, 否则,始终返回右边值。

结尾

javascript基础本章简单的介绍在这里,内容并不全面,还请多多见谅。如有错误,请指出。。。。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
setTimeout和setInterval的浏览器兼容性分析
Feb 27 Javascript
获取JavaScript用户自定义类的类名称的代码
Mar 08 Javascript
IE8下String的Trim()方法失效的解决方法
Nov 08 Javascript
JavaScript实现的多个图片广告交替显示效果代码
Sep 04 Javascript
Javascript编程之继承实例汇总
Nov 28 Javascript
JavaScript中数组添加值和访问值常见问题
Feb 06 Javascript
Bootstrap基本插件学习笔记之Popover提示框(19)
Dec 08 Javascript
微信端开发--登录小程序步骤
Jan 11 Javascript
ES6中的rest参数与扩展运算符详解
Jul 18 Javascript
详解cordova打包成webapp的方法
Oct 18 Javascript
Vue 指令实现按钮级别权限管理功能
Apr 23 Javascript
在js中修改html body的样式
Nov 11 Javascript
bootstrap侧边栏圆点导航
Jan 11 #Javascript
微信小程序开发(二)图片上传+服务端接收详解
Jan 11 #Javascript
JavaScript BASE64算法实现(完美解决中文乱码)
Jan 10 #Javascript
使用vue实现点击按钮滑出面板的实现代码
Jan 10 #Javascript
Mac下使用charles遇到的问题以及解决办法
Jan 10 #Javascript
vue2滚动条加载更多数据实现代码
Jan 10 #Javascript
简单实现IONIC购物车功能
Jan 10 #Javascript
You might like
在Windows版的PHP中使用ADO
2006/10/09 PHP
PHP无限分类代码,支持数组格式化、直接输出菜单两种方式
2011/05/18 PHP
PHP使用Session遇到的一个Permission denied Notice解决办法
2014/07/30 PHP
PHP实现163邮箱自动发送邮件
2016/03/29 PHP
CSS+JS构建的图片查看器
2006/07/22 Javascript
破除网页鼠标右键被禁用的绝招大全
2006/12/27 Javascript
jQuery 源代码显示控件 (Ajax加载方式).
2009/05/18 Javascript
jQuery动态设置form表单的enctype值(实现代码)
2013/07/04 Javascript
jQuery中:header选择器用法实例
2014/12/29 Javascript
jQuery中的pushStack实现原理和应用实例
2015/02/03 Javascript
js实现延时加载Flash的方法
2015/11/26 Javascript
jQuery插件ajaxFileUpload使用实例解析
2016/10/19 Javascript
JS实现PC手机端和嵌入式滑动拼图验证码三种效果
2017/02/15 Javascript
详解webpack+vue-cli项目打包技巧
2017/06/17 Javascript
Vue.js组件间通信方式总结【推荐】
2018/11/23 Javascript
JS中的算法与数据结构之常见排序(Sort)算法详解
2019/08/16 Javascript
浅谈vue 锚点指令v-anchor的使用
2019/11/13 Javascript
[01:08:10]2014 DOTA2国际邀请赛中国区预选赛 SPD-GAMING VS LGD-CDEC
2014/05/22 DOTA
python分割和拼接字符串
2013/11/01 Python
理解python多线程(python多线程简明教程)
2014/06/09 Python
利用Python中的mock库对Python代码进行模拟测试
2015/04/16 Python
Python实现将目录中TXT合并成一个大TXT文件的方法
2015/07/15 Python
Python利用正则表达式实现计算器算法思路解析
2018/04/25 Python
基于Numba提高python运行效率过程解析
2020/03/02 Python
python 子类调用父类的构造函数实例
2020/03/12 Python
Python Selenium安装及环境配置的实现
2020/03/17 Python
纯CSS3实现Material Design效果
2017/03/09 HTML / CSS
详解rem 适配布局
2018/10/31 HTML / CSS
html5定位获取当前位置并在百度地图上显示
2014/08/22 HTML / CSS
华丽的手绘陶瓷:MacKenzie-Childs
2017/02/04 全球购物
描述一下JVM加载class文件的原理机制
2013/12/08 面试题
大学生毕业自我鉴定范文
2013/11/03 职场文书
传播学专业毕业生自荐信
2013/11/04 职场文书
2014初中数学教研组工作总结
2014/12/19 职场文书
辞职信范文大全
2015/03/02 职场文书
五一晚会主持词
2015/07/01 职场文书