caller和callee的区别
①、caller
caller返回一个函数的引用,这个函数调用了当前的函数。
使用这个属性要注意:
1 这个属性只有当函数在执行时才有用
2 如果在javascript程序中,函数是由顶层调用的,则返回null
functionName.caller: functionName是当前正在执行的函数。
function outer(){
inner();
}
function inner(){
alert(inner.caller); //指向outer()
}
outer();
②、callee
callee返回正在执行的函数本身的引用,它是arguments的一个属性
使用callee时要注意:
1 这个属性只有在函数执行时才有效
2 它有一个length属性,可以用来获得形参的个数,因此可以用来比较形参和实参个数是否一致,即比较arguments.length是否等于arguments.callee.length
3 它可以用来递归匿名函数。
function test() {
console.log(arguments.callee);
}
test();
/* ƒ test() {
console.log(arguments.callee);
}*/
// 应用 ->递归匿名函数
var num = (function (n) {
if (n == 1)
return 1;
else return n * arguments.callee(n - 1);
}(5))
对象克隆
浅层克隆
var obj={
name:'abc',
sex:'0',
grade:1,
friend:{
name:"mike",
sex:0,
grade:1
},
card:[1,2,3]
}
var obj1={};
function clone(origin,target){
var target = target||{};
for(var prop in origin){
target[prop]=origin[prop];
}
return target;
}
var obj2=clone(obj,obj1);
console.log(obj2);
浅层拷贝是指当被拷贝对象含有数组或者对象值时,obj1拷贝的只是obj数组或者对象的引用,当增/删/改obj或者obj1的里的数组或者对象值时,obj1/obj中对应的数据也会被修改
例如
改变obj1对象中friend对象的name
相应的obj里的数据也会被改变
深度克隆
步骤
遍历对象 for(var prop in obj)
- hasOwnProperty()查找数组是否有某个属性
- 判断是不是原始值typeof()
- 原始值:直接拷贝
- 不是原始值:
判断是数组还是对象 instanceof toString constructor
建立相应的数组和对象
递归
var obj={
name:'abc',
sex:'0',
grade:1,
friend:{
name:"mike",
sex:0,
grade:1
},
card:[1,2,3]
}
var obj1={};
function deepClone(origin,target){
var target = target||{},
tostr=Object.prototype.toString;//ƒ toString() { [native code] }
arrstr="[object Array]"//数组
for(var prop in origin){
if(origin.hasOwnProperty(prop)){
if(typeof(origin[prop])!=="null"&&typeof(origin[prop])=='object'){
if(tostr.call(origin[prop])==arrstr){
//是数组
target[prop]=[];
}
else{
target[prop]={};
}
deepClone(origin[prop],target[prop]);
}
else{
target[prop]=origin[prop];
}
}
}
return target;
}
deepClone(obj,obj1)
深层拷贝不仅仅是数组或者对象引用值的拷贝,所以在改变obj1的数组或者对象的中的数值时,不会影响obj对应的数据的值
例如
改变obj1对象中friend对象的name
obj里的数据被改变了,但是相应的obj里的数据也会不被改变