打咩🙅,Javascript Object 你为什么这么多坑

this 指向的迷之行为

javascript 复制代码
const user = {
  name: "John",
  sayHi() {
    console.log(this.name);
  }
};

const sayHi = user.sayHi;
sayHi(); // 输出:undefined(严格模式下报错)

原因 :方法中的 this 取决于调用方式。当方法被单独调用时,this 指向全局对象(非严格模式)或 undefined(严格模式)。

解决方案

  • 使用箭头函数(但箭头函数无自己的 this
  • 使用 bind 绑定上下文:const sayHi = user.sayHi.bind(user);
  • 调用时指定上下文:sayHi.call(user);

深拷贝与浅拷贝的误会

javascript 复制代码
const obj = { a: 1, nested: { b: 2 } };
const shallowCopy = { ...obj };
shallowCopy.nested.b = 999;
console.log(obj.nested.b); // 输出:999(原对象被修改!)

原因 :展开运算符 ...Object.assign() 只能实现浅拷贝,嵌套对象仍是引用。

解决方案

  • 使用 JSON.parse(JSON.stringify(obj))(但无法处理函数、循环引用)
  • 使用 Lodash 的 _.cloneDeep()
  • 手动递归实现深拷贝

属性遍历的隐藏属性

javascript 复制代码
const obj = { a: 1 };
Object.defineProperty(obj, 'b', { value: 2, enumerable: false });

console.log(Object.keys(obj)); // 输出:["a"]
for (let key in obj) console.log(key); // 输出:"a"
console.log('b' in obj); // 输出:true

原因 :对象属性具有 enumerable 特性,默认值为 true。通过 defineProperty 定义的属性若设为不可枚举,则无法被 for...inObject.keys() 遍历,但仍可通过 in 运算符判断存在性。

解决方案

  • 使用 Object.getOwnPropertyNames() 获取所有自身属性(包括不可枚举)
  • 使用 Reflect.ownKeys() 获取所有键(包括 Symbol)

对象比较的错觉

javascript 复制代码
console.log({} === {}); // false
console.log(NaN === NaN); // false
console.log(Object.is({}, {})); // false
console.log(Object.is(NaN, NaN)); // true

原因 :对象通过引用比较,即使内容相同,两个不同对象也不相等。而 NaN 在常规比较中不等于自身,但 Object.is() 能正确处理。

解决方案

  • 深比较:递归比较每个属性值
  • 使用第三方库如 Lodash 的 _.isEqual()

ES6 的 Proxy 陷阱

javascript 复制代码
const target = {};
const proxy = new Proxy(target, {
  get(obj, prop) {
    return prop in obj ? obj[prop] : 0;
  }
});

proxy.a = 100;
console.log(proxy.a); // 100
console.log(proxy.b); // 0
console.log(target.b); // undefined(原对象未被修改)

原因:Proxy 可以拦截对象操作,但如果不显式操作目标对象,可能导致代理对象与原对象行为不一致。

解决方案

  • 始终通过代理对象操作
  • 在处理器中正确处理反射方法

JSON 序列化的黑洞

javascript 复制代码
const obj = { 
  date: new Date(),
  fn: () => console.log("Hi"),
  undefinedProp: undefined
};
const json = JSON.stringify(obj);
console.log(json); // 输出:{"date":"2023-10-01T12:00:00.000Z"}

原因JSON.stringify 会忽略 undefined 和函数,并将 Date 对象转为字符串。

解决方案

  • 自定义 toJSON 方法
  • 使用 JSON.stringifyreplacer 参数处理特殊类型
相关推荐
Hooray11 分钟前
用时7天,花费30元,我vibe coding这个网站
前端·agent·ai编程
小小高不懂写代码24 分钟前
RAG--检索增强生成--原理及实战
前端·人工智能
空中海27 分钟前
04 工程化、质量体系与 React 生态
前端·ubuntu·react.js
好运的阿财1 小时前
OpenClaw工具拆解之host_workspace_write+host_workspace_edit
前端·javascript·人工智能·机器学习·ai编程·openclaw·openclaw工具
XiYang-DING1 小时前
JavaScript
开发语言·javascript·ecmascript
ffqws_2 小时前
Spring Boot 接收前端请求的四种参数方式
前端·spring boot·后端
空中海2 小时前
02 React Native状态、导航、数据流与设备能力
javascript·react native·react.js
是安迪吖2 小时前
企业资产管理系统练习
前端·ai
zhouwy1132 小时前
AI 编程工具结合 Figma MCP 实现前端设计高保真还原
前端·人工智能·figma
kyriewen3 小时前
WebAssembly:前端界的“外挂”,让C++代码在浏览器里跑起来
前端·c++·webassembly