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 相关文章推荐
javascript 全等号运算符使用说明
May 31 Javascript
ExtJS4 表格的嵌套 rowExpander应用
May 02 Javascript
JavaScript检查子字符串是否在字符串中的方法
Feb 03 Javascript
微信小程序 在线支付功能的实现
Mar 14 Javascript
Vue.js render方法使用详解
Apr 05 Javascript
js 实现复选框只能选择一项的示例代码
Jan 23 Javascript
vue组件(全局,局部,动态加载组件)
Sep 02 Javascript
JavaScript格式化json和xml的方法示例
Jan 22 Javascript
Vue实现固定定位图标滑动隐藏效果
May 30 Javascript
微信小程序利用button控制条件标签的变量问题
Mar 15 Javascript
浅谈vant组件Picker 选择器选单选问题
Nov 04 Javascript
VUE项目实现主题切换的多种方法
Nov 26 Vue.js
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
帅气的琦玉老师
2020/03/02 日漫
PHP中文件缓存转内存缓存的方法
2011/12/06 PHP
php对数组排序的简单实例
2013/12/25 PHP
PHP date()函数警告: It is not safe to rely on the system解决方法
2014/08/20 PHP
php中实现可以返回多个值的函数实例
2015/03/21 PHP
Yii2 加载css、js 载静态资源的方法
2017/03/10 PHP
php使用redis的几种常见操作方式和用法示例
2020/02/20 PHP
PHP中->和=>的含义及使用示例解析
2020/08/06 PHP
通用于ie和firefox的函数 GetCurrentStyle (obj, prop)
2006/12/27 Javascript
js 绑定带参数的事件以及手动触发事件
2010/04/27 Javascript
有关于eclipse配置spket需要注意的一些地方
2013/04/07 Javascript
获取内联和链接中的样式(js代码)
2013/04/11 Javascript
JQuery each()嵌套使用小结
2014/04/18 Javascript
基于javascript实现全国省市二级联动下拉选择菜单
2016/01/28 Javascript
动态加载JavaScript文件的两种方法
2016/04/22 Javascript
Bootstrap每天必学之标签页(Tab)插件
2020/08/09 Javascript
原生js和jquery分别实现横向导航菜单效果
2016/05/13 Javascript
jQuery 获取多选框的值及多选框中文的函数
2016/05/16 Javascript
微信小程序 wx.login解密出现乱码的问题解决办法
2017/03/10 Javascript
axios发送post请求,提交图片类型表单数据方法
2018/03/16 Javascript
微信小程序form表单组件示例代码
2018/07/15 Javascript
Vue使用localStorage存储数据的方法
2019/05/27 Javascript
vue中filters 传入两个参数 / 使用两个filters的实现方法
2019/07/15 Javascript
python3正则提取字符串里的中文实例
2019/01/31 Python
Python使用QQ邮箱发送邮件实例与QQ邮箱设置详解
2020/02/18 Python
python输出数学符号实例
2020/05/11 Python
HTML5 Web 存储详解
2016/09/16 HTML / CSS
HTML5 Canvas draw方法制作动画效果示例
2013/07/11 HTML / CSS
竞聘副主任科员演讲稿
2014/01/11 职场文书
警察先进个人事迹材料
2014/05/16 职场文书
民主评议党员自我评议范文2014
2014/09/26 职场文书
介绍信模板
2015/01/31 职场文书
【HBU】数据库第四周 单表查询
2021/04/05 SQL Server
OpenCV-Python实现油画效果的实例
2021/06/08 Python
MyBatis-Plus 批量插入数据的操作方法
2021/09/25 Java/Android
MySQ InnoDB和MyISAM存储引擎介绍
2022/04/26 MySQL