js的深拷贝和浅拷贝?啥情况讲解下??底层堆栈空间??object.prototype.toString.call(),还有bind,的具体使用?

js的深拷贝和浅拷贝?啥情况讲解下??底层堆栈空间??object.prototype.toString.call(),还有bind,的具体使用?还有instanceof对象的实例,还有哪个方法可以直接获取到我定义的数据是什么类型的。哟哪几种数据类型?包括哪些?

1. 堆(Heap)与 栈(Stack):内存的真相

在 JS 里,内存被分为两块:

  • 栈(Stack) :空间小、速度快。存放基本数据类型 (String, Number, Boolean, Null, Undefined, Symbol, BigInt)和引用类型的地址

  • 堆(Heap) :空间大。存放引用数据类型(Object, Array, Function)。


2. 深拷贝 vs 浅拷贝

这是由于"堆栈分离"导致的现象:

  • 浅拷贝(Shallow Copy)

    • 情况:只复制了栈里的"地址"。

    • 后果:新旧对象指向同一个堆空间。改了新对象的属性,旧对象的也跟着变。

    • 实现Object.assign(){...obj}arr.slice()

  • 深拷贝(Deep Copy)

    • 情况:在堆里开辟了一块全新的空间,把内容全写进去。

    • 后果:两者完全独立,互不影响。

    • 实现

      1. JSON.parse(JSON.stringify(obj))(简单粗暴,但不能处理函数和循环引用)。

      2. 递归手写(面试最爱)。

      3. structuredClone(obj)(现代浏览器原生支持)。


3. 类型检测:到底我是谁?

JS 有 8 种 数据类型:

  • 基本类型Number, String, Boolean, Undefined, Null, Symbol, BigInt

  • 引用类型Object(包括 Array, Function, Date 等)。

怎么获取准确类型?
  1. typeof :快,但对 nullArray 都会返回 "object"(这是 JS 的陈年 BUG)。

  2. instanceof :判断对象实例 是否属于某个构造函数(顺着原型链找)。比如 [] instanceof Arraytrue

  3. Object.prototype.toString.call()终极方案): 它可以直接穿透一切伪装,告诉你的底层"户籍"。

    JavaScript

    复制代码
    Object.prototype.toString.call([]);      // "[object Array]"
    Object.prototype.toString.call(123);     // "[object Number]"
    Object.prototype.toString.call(null);    // "[object Null]"
    Object.prototype.toString.call(new Date()); // "[object Date]"

4. bind 的具体使用

bindcallapply 的兄弟,但它最特别。

  • 作用 :创建一个新函数,强制把这个新函数的 this 绑定到你指定的对象上。

  • 区别call/apply 会立即执行函数,而 bind 是返回一个新函数,不立即执行

实战场景: 在 Vue2 或者是旧的 React 类组件里,防止方法里的 this 丢失。

JavaScript

复制代码
const device = {
  name: '感应器',
  getName: function() {
    console.log(this.name);
  }
};

const unboundGet = device.getName;
unboundGet(); // undefined (因为此时 this 指向全局)

const boundGet = device.getName.bind(device);
boundGet(); // '感应器' (强制锁定了 this)

5. instanceof 的底层原理

它其实就是在玩**"连连看"**。 L instanceof R 的原理是:看 L__proto__ 是不是等于 Rprototype。如果不等于,就继续往 L 的爷爷辈(__proto__.__proto__)找,直到找到或者到头为止。

js的深拷贝和浅拷贝还不明白??本博主教育你!!

1. 核心:为什么会有这两种拷贝?

这得从 JS 的内存管理说起。JS 把数据存在两个地方:栈(Stack)堆(Heap)

  • 基本类型 (数字、字符串等):直接存在里,值就在那。

  • 引用类型 (对象、数组):内容存在 里,但在里存了一个"地址"(就像一把指向仓库的钥匙)。


2. 浅拷贝(Shallow Copy):只复制钥匙

当你做浅拷贝时,JS 只是在栈里又配了一把一模一样的钥匙

  • 结果:两个变量指向堆里的同一个"仓库"。

  • 后果:你拿着新钥匙进仓库改了东西,老王拿着旧钥匙进去一看,东西也变了。

常见操作:

  • Object.assign({}, oldObj)

  • { ...oldObj } (展开运算符)

  • Array.prototype.slice()

代码演示:

JavaScript

复制代码
let a = { name: '张三', favorite: { food: '火锅' } };
let b = { ...a }; // 浅拷贝

b.name = '李四'; 
console.log(a.name); // '张三' (基本类型在栈里,互不影响)

b.favorite.food = '串串';
console.log(a.favorite.food); // '串串' (引用类型指向同一个堆,一起变了!)

3. 深拷贝 (Deep Copy):直接克隆一个新仓库

深拷贝会把堆里的东西全部复制一份,塞进一个新的堆空间,并给你一把指向新空间的钥匙。

  • 结果:两个变量完全独立。

  • 后果:你在新仓库里把天拆了,老王的旧仓库也纹丝不动。

常见操作:

  1. 最简单(有缺陷)JSON.parse(JSON.stringify(obj))

    • 缺点:不能拷贝函数、undefined、正则,会丢失原型链。
  2. 现代原生structuredClone(obj)

    • 优点:2022年后的浏览器原生支持,非常强大。
  3. 终极武器 :手写递归或使用 Lodash_.cloneDeep


4. 怎么获取数据类型?(你要的那个方法)

你刚才问有没有一个方法能直接看穿所有类型?有!就是我提到的 "万能判定法"

typeof 太弱了(数组、对象、null 它都说是 object),我们要用这个:

JavaScript

特性 浅拷贝 深拷贝
复制内容 复制对象的引用(地址) 复制对象的所有层级结构
内存位置 栈中地址不同,堆中内容相同 栈中地址不同,堆中内容也不同
相互影响 修改嵌套对象时,会互相影响 彻底隔离,互不影响
性能 慢(递归耗时)
复制代码
function getType(target) {
    // 截取字符串,只保留中间的类型名,比如 "Array"
    return Object.prototype.toString.call(target).slice(8, -1);
}

console.log(getType([]));        // "Array"
console.log(getType({}));        // "Object"
console.log(getType(null));      // "Null"
console.log(getType(new Date())); // "Date"
相关推荐
浩星1 小时前
「React + Cesium 最佳实践」完整工程化方案
前端·vue.js·react.js
1314lay_10071 小时前
el-table表格数据分页切片,导致表格的多选失效
javascript·vue.js·elementui
qq_12084093712 小时前
Three.js 模型加载稳定性实战:从资源失败到可用发布的工程化方案
前端·javascript·vue.js·vue3·three.js
skywalk81632 小时前
mock数据什么意思?前端应用mock
前端
阿正的梦工坊2 小时前
JavaScript 闭包:从入门到精通
开发语言·javascript·ecmascript
weixin199701080162 小时前
《闲鱼商品详情页前端性能优化实战》
前端·性能优化
qq_12084093712 小时前
Three.js 性能实战:大场景从 15FPS 到 60FPS 的工程化优化路径
开发语言·前端·javascript
Code-keys2 小时前
【gdb工具】 使用详细介绍
前端·chrome
guhy fighting2 小时前
使用vue-virtual-scroller导致打包报错
前端·javascript·vue.js·webpack