1、引用
1.1 概念:
变量并不实际存储"对象"。变量存储指向对象的引用。引用就像指针,是对象的"存储地址"。换句话说,变量并不存储对象本身,而是存储类似于指针的东西。在JavaScript中,但我们需要知道,当对象赋值给变量时它肯定指向相应的对象。当我们使用属性与方法时,JavaScript将负责根据引用获取对象并访问其属性。
1.2 值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol。
// JS基本数据类型的传递(变量之间的赋值操作)是值传递 互不相干
1.3 引用数据类型(对象类型):对象(Object)、数组(Array)、函数(Function),还有两个特殊的对象:正则(RegExp)和日期(Date)。
// JS复合数据类型(数组,对象,function)的传递(变量之间的赋值操作)是引用传递 同生共死
// 函数表达式(匿名函数赋值给一个变量)
// 解除数组引用核心: 遍历数组赋值给新数组 或者 使用数组对象内置方法得到一个新数组
// 注意: 该方式只能解决外层引用问题,如果内层数据再次出现数组或者对象, 内层数据还是会引用
1.4 浅拷贝:
指的是仅拷贝对象的指针地址,而不复制对象本身,新旧对象还是"共享同一块内存",这样会使被拷贝的对象会因为拷贝的对象的数据改变而改变
1.5 深拷贝:
1.5.1 拷贝一个对象的数据之前先给拷贝的对象创建一个堆地址,创造一个一模一样的值 , 新值跟原值不共享内存, 这样当拷贝的对象指向的堆中的数据改变时,被拷贝的对象堆中的数据并不会被改变
1.5.2 使用ES6新增的一个Object.assign()合并对象的方法 实现的是"浅拷贝"
语法:// Object.assign(目标对象, 源对象1, 源对象2, 源对象3... )
// 返回值 修改后的目标对象。
// 注意: 合并的时候, 会把源对象列表中的属性添加到目标对象中, 如果同名属性将覆盖属性值
1.5.3 实现深拷贝
1 JSON.stringify() 与 JSON.parse() 配合使用
// JSON.stringify()把JSON对象转成JSON字符串的方法
// JSON.parse() 把JSON字符串转成JSON对象
// 注意: 该种方式不能拷贝对象中的方法以及属性值为undefined的属性
2 自己封装函数
// obj参数表示需要被深拷贝的对象
function deepCopy(obj) {
// 判断obj参数的数据类型是否为"object"
if (typeof obj !== "object") {
return obj;
}
// 如果obj是对象,我们就创建新的空对象
// 如果obj是数组,我们就创建新的空数组
var newObj = Array.isArray(obj) ? [] : {};
// 遍历obj
for (var attr in obj) {
if (typeof obj[attr] !== "object") {
// 如果obj[attr]的数据类型是基本数据类型,可以直接赋值给newObj
newObj[attr] = obj[attr];
} else {
// 如果obj[attr]的数据类型是引用数据类型,需要再次进行deepCopy
newObj[attr] = deepCopy(obj[attr]);
}
}
// 返回newObj对象
return newObj;
}
2、高阶函数:
把函数当做参数传递进另一个函数中 或者 把函数当做返回值返回出来
// 高阶函数情况1: 把函数当做参数传递进另一个函数中, 我们使用的比较多的就是回调函数
// 高阶函数情况2: 把函数当做返回值返回出来
3、闭包
// 闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。在 JavaScript 中,闭包会随着函数的创建而被同时创建。
// 闭包让开发者可以从内部函数访问外部函数的作用域就是表示内层函数可以访问外层函数定义的形参以及变量
// 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。我们知道Javascript语言的特殊之处,就在于"函数内部可以直接读取全局变量"。另一方面,在函数外部自然无法读取函数内的局部变量。而闭包就是能够读取其他函数内部变量的函数。在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
// 创建闭包最简单方式就是函数嵌套函数
// 闭包的特性
// 1.函数内再嵌套函数
// 2.内部函数可以引用外层函数的形参和局部变量
// 3.被引用的形参和局部变量不会被垃圾回收机制回收
eg: 点击事件,获取索引号:
// 解决方式一: 自定义属性
// 解决方式二: 闭包