一:js深拷贝
在JS中,数据类型分为基本数据类型和引用数据类型两种,对于基本数据类型来说,它的值直接存储在栈内存中,而对于引用类型来说,它在栈内存中仅仅存储了一个引用,而真正的数据存储在堆内存中。深拷贝作用在引用类型上!例如:Object,Array。深拷贝不会拷贝引用类型的引用,而是将引用类型的值全部拷贝一份,形成一个新的引用类型,这样就不会发生引用错乱的问题,使得我们可以多次使用同样的数据,而不用担心数据之间会起冲突
如何实现深拷贝?
1:序列化以及反序列化,JSON.stringify()以及JSON.parse()
//这个方法只适用于此类简单对象 严格来说 不算是深拷贝 但依然具有效果
let obj = {
a: 1,
b: 2,
c: 3
}
let objclone = Object.assign({}, obj);
objclone.b = 5;
console.log(obj.b); // 2
console.log(objclone.b); // 5
2: 递归拷贝 此方法借鉴于老同学前端郝晨光
// 定义一个深拷贝函数 接收目标target参数
function deepClone(target = '') {
// 定义一个变量
let result;
// 如果当前需要深拷贝的是一个对象的话
if (typeof target === 'object') {
// 如果是一个数组的话
if (Array.isArray(target)) {
result = []; // 将result赋值为一个数组,并且执行遍历
for (let i in target) {
// 递归克隆数组中的每一项
result.push(deepClone(target[i]))
}
// 判断如果当前的值是null的话;直接赋值为null
} else if(target===null) {
result = null;
// 判断如果当前的值是一个RegExp对象的话,直接赋值
} else if(target.constructor===RegExp){
result = target;
}else {
// 否则是普通对象,直接for in循环,递归赋值对象的所有值
result = {};
for (let i in target) {
result[i] = deepClone(target[i]);
}
}
// 如果不是对象的话,就是基本数据类型,那么直接赋值
} else {
result = target;
}
// 返回最终结果
return result;
}
let obj = {
a: {
c: /a/,
d: undefined,
b: null
},
b: function () {
console.log(this.a)
},
c: [
{
a: 'c',
b: /b/,
c: undefined
},
'a',
3
]
}
let objclone = deepClone(obj);
console.log(objclone);
3:ES6 新语法 ...展开
//这个方法只适用于此类简单对象 严格来说 不算是深拷贝 但依然具有效果
let obj = { a:10 }
let objclone = {...obj}
objclone.a = 5
console.log(obj,objclone) // 10 5
this指向问题
js常考点 主要是考察bind,call,apply的使用的区别
相同点:
1:都能改变this指向
2:都能传递参数
3:都能通过方法"."方法名调用
不同点
1:函数名不同
2:参数传递方式不同
3:改变this指向的时机不同(bind在复制时改变,其他两个在调用时改变)
4:参数传递时机不同
举例: 完善以下函数 ,使 f 的 this 指向指定的对象oTarget(题目来源牛客网)
function bindThis(f, oTarget) {
}
//这是用来调用验证的函数
function() {
var r = bindThis(function(a, b) {
return this.test + a + b
}, {
test: 2
})(2, 3);
return r === 7;
}
答案:
//第一种:
function bindThis(f, oTarget) {
return function(){
return f.call(oTarget,...arguments)
}
} //使用call方法 注意arguments对象的参数形式
//第二种:
function bindThis(f, oTarget) {
return function(){
return f.apply(oTarget,arguments)
}
} //使用apply方法
//第三种:
function bindThis(f, oTarget) {
return f.bind(oTarget)
}// bind方法 直接绑定this指向