打咩🙅,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 参数处理特殊类型
相关推荐
IT_陈寒3 分钟前
Redis 性能骤降50%?这5个隐藏配置陷阱你可能从未注意过
前端·人工智能·后端
躺着听Jay4 分钟前
【1267 - Illegal mix of collations 】mysql报错解决记录
java·linux·前端
Dragon Wu20 分钟前
ReactNative Expo 使用总结(基础)
javascript·react native·react.js
真上帝的左手37 分钟前
24. 前端-js框架-Electron
前端·javascript·electron
毛发浓密的女猴子42 分钟前
Git Pull 策略完全指南:Merge、Rebase、Fast-forward 深度对比
前端
夏小花花43 分钟前
<editor> 组件设置样式不生效问题
java·前端·vue.js·xss
PieroPC43 分钟前
用 nicegui 3.0 + sqlite3 做个简单博客
前端·后端
weixin_3077791344 分钟前
Jenkins Ioncions API 插件:现代化图标库在持续集成中的应用
java·运维·开发语言·前端·jenkins
兔子零10241 小时前
零硬件交互:如何用纯前端把摄像头变成 4000 个粒子的魔法棒?
前端·算法
北辰alk1 小时前
Vue Router 组件内路由钩子全解析
前端·vue.js