基本数据与引用数据的区别

2022-10-17  本文已影响0人  于美美

基本数据: Undefined、Null、Boolean、Number、String、Symbol
引用数据: Object、Array、Function、RegExp、Date

注意: javascript不允许直接访问内存位置,因此就不能直接操作对象所在的内存空间

一、基本数据与引用数据区别

基本数据:

引用数据:


当它们复制值时:
基本数据:把基本数据通过变量赋值给另一个变量时,基本数据会被复制到新变量的位置
引用数据:把引用数据通过变量赋值给另一个变量时,存储在变量中的值也会被复制到新变量所在的位置。区别就在于,这里复制的值实际上是一个指针,它指向存储在堆内存中的对象,操作完成后,两个变量实际上指向同一个对象,因此一个对象上面的变量会在另一个对象上反映出来,就会有深拷贝与浅拷贝

基本数据.jpeg 引用数据.jpeg
二、深拷贝与浅拷贝的区别

深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的。

深拷贝:将一个对象从内存中完整的拷贝一份出来,从堆数据开辟一个新的区域存放新对象,新旧对象不共享同一个内存,且修改对象不会影响另一个对象

浅拷贝:如果对象的属性是基本类型,那拷贝的就是基本类型的值;如果是引用类型,那拷贝的就是指针,新旧对象共享同一块内存

三、深拷贝与浅拷贝的一些实现

浅拷贝

let obj1 = {
  name: 'jack',
  age: 19,
  hobby: ['swimming', 'walking', 'go']
}

let obj2 = {...obj1}

obj2.age=30
obj2.hobby[0] = 'haha' 
// obj1 ==> { age: 19, name: "jack", hobby:  ["haha", "walking", "go"] }

以上:浅拷贝,第一层的数据如果是基本类型,是可以实现拷贝的,但是数据是引用类型,修改新对象的属性就会影响原对象的属性

let obj2 = Object.assign({}, obj1);
let arr2 = arr1.concat([]);
let arr2 = arr1.slice();

注意:当原数据(object)只有一层时,就是深拷贝; 当Array只有一层的时候,是深拷贝;所以当原数据进行浅拷贝,改变arr2的arr[1],而原数据arr1中的arr1[1]没有改变

深拷贝

let obj2 = JSON.parse(JSON.stringify(obj1))
let arr2 = JSON.parse(JSON.stringify(arr1))

Object、Array可以通过JSON.parse(JSON.stringify())实现深拷贝,但是Date跟Function却不能

//  需要引入jQuery库哦
let obj2 = jQuery.extend(true, {}, obj1)
// 检测数据类型的功能函数
const checkedType = (target) => Object.prototype.toString.call(target).replace(/\[object (\w+)\]/, "$1").toLowerCase();
// 实现深拷贝(Object/Array)
const clone = (target) => {
    let result;
    let type = checkedType(target);
    if(type === 'object') result = {};
    else if(type === 'array') result = [];
    else  return target;
    for (let key in target) {
        if(checkedType(target[key]) === 'object' || checkedType(target[key]) === 'array') {
            result[key] = clone(target[key]);
        } else {
            result[key] = target[key]; 
        }
    }
    return result;
}

调用一下手写递归实现深拷贝方法:

const obj = {
    name: 'Chen',
    detail: {
        age: '18',
        height: '180',
        bodyWeight: '68'
    },
    hobby: ['see a film',  'write the code',  'play basketball', 'tourism']
}

const obj1 = clone(obj);
console.log(obj1); // { name: 'Chen',detail: { age: '18', height: '180', bodyWeight: '68' },  hobby: [ 'see a film', 'write the code', 'play basketball', 'tourism' ]}
console.log(obj1 === obj); // false
判断数据类型
let s = 'string'
let num = 10
let b = true
let u = undefined
let nu = null 
let o = new Object()

console.log(typeof s) //  "string"
console.log(typeof num) // "number"
console.log(typeof b) // "boolean"
console.log(typeof u) // "undefined"
console.log(typeof nu) // "object"
console.log(typeof o) // "object"
function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
const auto = new Car('Honda', 'Accord', 1998);

console.log(auto instanceof Car) // expected output: true
console.log(auto instanceof Object) // expected output: true

console.log([1,2,3] instanceof Array ); // true
console.log(new Date() instanceof Date ); // true
console.log(function f() {} instanceof Function ); // true
console.log(Object.prototype.toString.call("jerry"));//[object String]
console.log(Object.prototype.toString.call(12));//[object Number]
console.log(Object.prototype.toString.call(true));//[object Boolean]
console.log(Object.prototype.toString.call(undefined));//[object Undefined]
console.log(Object.prototype.toString.call(null));//[object Null]
console.log(Object.prototype.toString.call({name: "jerry"}));//[object Object]
console.log(Object.prototype.toString.call(function(){}));//[object Function]
console.log(Object.prototype.toString.call([]));//[object Array]
console.log(Object.prototype.toString.call(new Date));//[object Date]
console.log(Object.prototype.toString.call(/\d/));//[object RegExp]
// 封装获取数据类型
function getType(value) {
    let type = typeof value;
    if (type !== 'object') { // 如果是基本数据类型,直接返回
        return type;
    }
    // 如果是引用数据类型,再进一步判断,正则返回结果
    return Object.prototype.toString.call(value).replace(/^\[object (\S+)\]$/, '$1');
}
 
console.log(getType(123)) // 'number'
console.log(getType('aaa')) // 'string'
console.log(getType(() => {})) // 'function'
console.log(getType([])) // 'Array'
console.log(getType({})) // 'Object'
console.log(getType(null)) // 'Null'

参考文章:前端面试 第三篇 js之路 深拷贝与浅拷贝

上一篇 下一篇

猜你喜欢

热点阅读