前端充电站--手写深拷贝重温值类型、引用类型

121 阅读2分钟

值类型都是在栈中存储的

let a=100;
let b=a;
a=200;
console.log(a)  //输出为200
console.log(b)  //输出为100

引用类型保存的是内存地址

let a={age:21}
let b=a;
b.age=22;

console.log(a.age)  
//ab保存的是同一内存地址 输出为22

常用引用类型

const obj={x:100}  //对象
const arr=["a","b","c"]  //数组
const n=null  //特殊引用类型,指针指向为空地址
function fn(){} //特殊引用类型,但不用于存储数据,所以没有"拷贝、复制函数"的说法

typeof运算符的用法

--能够判断所有值类型
let a;  console.log(typeof a);  //'undefined' 字符串
let a=100;   console.log(typeof a);  // 'number' 
let a='100'; console.log(typeof a);  // 'string'
let a=true;  console.log(typeof a);  // 'boolean'
let a=Symbol('100');console.log(typeof a);//'symbol'


--识别函数 
typeof console.log; //'function'
console.log(typeof function(){}) //'function'

--能识别引用类型(不能在继续识别)
typeof null //'object'
typeof ["a"] //'object'
typeof {a:a} //'object'
!!!很明显用来判断是否是数组或对象用typeof是不够的

for-in循环的基本用法

对于数组迭代出来的是数组下标,对于对象迭代出来的是对象的属性;

for(变量 in 数组){
	执行的代码  //变量是数组的下标
}

var a = ["a","b","c"];
for(var el in a){
  alert(a[el]);
} //依次输出为 a b c

------------------------------

for(变量 in 对象){
	执行的代码  //变量是对象的属性
}

var obj = {  
  l: "lin",  
  t: "tong",  
  h: "hui"  
}  

for(var v in obj){  
  console.log(obj[v]);  
}  //依次输出 lin tong hui

for-in循环会遍历到原型链上的属性

Object.prototype.opps="opps";   // 修改Object.prototype  
var person ={ name: 'lth' };
for (var key in person) {
	console.log(key, person[key]); //这里用person[key]而不是person.key
} 

//依次输出为 name lth  opps opps

//有时候我们并不想考虑原型链上的属性可以用hasOwnProperty()来过滤
Object.prototype.opps="opps";   // 修改Object.prototype  
var person ={ name: 'lth' };
for (var key in person) {
	if(person.hasOwnProperty(key)){
    	console.log(key, person[key]); //这里用person[key]而不是person.key
    }
}

//依次输出为 name lth(成功过滤了原型链上的属性)

手写一个深拷贝

该深拷贝实现原理:
var a={name:'lth'};
var b={}
b['name']=a['name']  //等号右边已经是属性值
b.name="yoho"
console.log(a.name)  //输出为 'lth'  改变b不在影响a

const obj1={
  age:20,
  name:'lth',
  address:{
  	city:'xiamen'
  },
  arr:['l','t','h']
}

function deepClone(obj){
	
    //obj==null 判断了null和undefined两种情况
    //意思是该对象是基本值(number、string、boolen、symbol)或者null和undefined
	if(typeof obj != 'object' ||  obj==null){
    	return obj;  //这种情况可以直接返回原值
    }
    
    let result; //接下来还得继续判断是对象还是数组
    if(obj instanceof Array){
    	result=[]
    }else{
    	result={}
    }
    
    for(key in obj){
    	if(obj.hasOwnProperty(key)){
        	//直到obj[key]能返回自身的时候才会赋值给result[key]
        	result[key]=deepClone(obj[key])   
        }
    }
    
    return result;

}

const obj2=deepClone(obj1)