写在前面
本文记录的是我不熟悉或者我认为值得注意的地方,并不是书上知识点的概括
第4章 变量、作用域和内存问题
对象是按引用传递的(我理解的是传值其实传的是一个指针,该指针指向内存中的某个对象)。举例如下:
const a = {name: 'aaa'}
const b = a // 这时候a和b其实指向的是同一个对象
console.log(b.name) // aaa
b.name = 'bbb'
console.log(b.name) // bbb
console.log(a.name) // bbb 在改变b时a也被改变了
对于简单的对象(属性的值都为基本数据类型),赋值时采用const b = {...a}
或者const b = Object.assign({}, a)
可以使得b
中的对象是一个新对象
Lodash
提供了cloneDeep()
函数用于深拷贝
对象按引用传递是因为这样比较节约内存(毕竟多个对象其实只存了一份嘛),弊端就是容易引起不被希望的变化。
JS具有自动垃圾回收机制,开发人员不用关心内存使用问题,其原理是找出不再继续使用的变量,释放其占用的内存
最常用的回收方式是标记清除
,另一个不太常见的是引用计数
在引用计数
中,无法处理循环引用
(对象a
中包含指向b
的指针,对象b
中也包含指向a
的指针),举例如下
function problem() {
const a = {}
const b = {}
a.obj = b
b.obj = a
}
可以通过在函数结尾断开引用来解决循环引用
的问题,如下
function problem() {
const a = {}
const b = {}
a.obj = b
b.obj = a
// 别的啥啥操作
// 设为null即可
a.obj = null
b.obj = null
}
优化内存占用:无用的数据将其值设为null
第5章 引用类型
引用类型的值(对象)是引用类型的一个实例
新对象是new
操作符后面跟一个构造函数
来创建的
数组的sort()
方法默认是按从小到大排序,会根据每一项的toString()
方法得到的字符串进行排序。由于是比较的是字符串,在大多数情况下,排序结果不是我们期望的(比如'10'<'5'
),我们需要自己去写一个排序函数传给sort()
数组的concat()
可以接受多个参数,如下
const a = [1, 2]
const b = a.concat(3, [4, 5])
console.log(b) // [1, 2, 3, 4, 5]
数组的splice()
用于在数组中插入一个或者多个值,如下
const a = [1, 4, 5]
a.splice(1, 0, 2, 3) // 接收的参数依次为 index,要删除的元素个数,要插入的元素们
console.log(a) // [1, 2, 3, 4, 5]
所以数组的splice()
也可用于替换数组中的某些项,如下
const a = [1, 2, 3, 4, 5]
a.splice(1, 2, 22, 33)
console.log(a) // [1, 22, 33, 4, 5]
由于函数也是对象,所以函数名其实是一个指向函数对象的指针
定义一个函数可以用函数声明 function funcName() {}
或者函数表达式 const func = function() {}
, 建议用函数表达式
定义函数,好处是定义之后不可被修改,也不会存在函数声明提升
函数内部有两个特殊对象,arguments
和this
,arguments
是一个类数组对象,包含着所有传入函数中的参数,this
指向的是函数执行的环境对象
字符串的toLocaleLowerCase()
是针对地区作了特殊处理的(不同地区对于某些值的转换规则会有些不一样),相对于toLowerCase()
来说更安全
完。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。