打咩🙅,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 参数处理特殊类型
相关推荐
weixin_4435669814 分钟前
CSS 预处理器
前端·css
excel23 分钟前
webpack 核心编译器 第一节
前端
大怪v34 分钟前
前端佬们!塌房了!用过Element-Plus的进来~
前端·javascript·element
拉不动的猪1 小时前
electron的主进程与渲染进程之间的通信
前端·javascript·面试
软件技术NINI1 小时前
html css 网页制作成品——HTML+CSS非遗文化扎染网页设计(5页)附源码
前端·css·html
fangcaojushi1 小时前
npm常用的命令
前端·npm·node.js
阿丽塔~1 小时前
新手小白 react-useEffect 使用场景
前端·react.js·前端框架
鱼樱前端2 小时前
Rollup 在前端工程化中的核心应用解析-重新认识下Rollup
前端·javascript
m0_740154672 小时前
SpringMVC 请求和响应
java·服务器·前端
加减法原则2 小时前
探索 RAG(检索增强生成)
前端