欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文解析JS如何準(zhǔn)確獲取對(duì)象自身的屬性

 更新時(shí)間:2025年09月19日 09:39:47   作者:LuckySusu  
在 JavaScript 開發(fā)中,我們經(jīng)常需要遍歷對(duì)象的屬性,本文將深入講解如何準(zhǔn)確獲取對(duì)象非原型鏈上的屬性(即“自身屬性”),并結(jié)合你提供的代碼,給出最佳實(shí)踐,有需要的可以了解下

在 JavaScript 開發(fā)中,我們經(jīng)常需要遍歷對(duì)象的屬性。但你是否遇到過(guò)這樣的問(wèn)題:

“為什么遍歷一個(gè)簡(jiǎn)單對(duì)象時(shí),會(huì)多出一些意想不到的方法?”

這是因?yàn)?for...in 循環(huán)會(huì)遍歷對(duì)象自身 + 原型鏈上所有可枚舉的屬性。如果我們只想獲取對(duì)象“自己”的屬性,就必須使用 hasOwnProperty() 方法進(jìn)行過(guò)濾。

本文將深入講解如何準(zhǔn)確獲取對(duì)象非原型鏈上的屬性(即“自身屬性”),并結(jié)合你提供的代碼,給出最佳實(shí)踐。

一、問(wèn)題背景:for...in的“陷阱”

看一個(gè)經(jīng)典例子:

function Person(name) {
  this.name = name;
}

Person.prototype.sayHello = function () {
  console.log(`Hello, I'm ${this.name}`);
};

const person = new Person('Alice');

// 直接使用 for...in
for (let key in person) {
  console.log(key);
}
// 輸出:
// name
// sayHello  ← 這是原型上的方法,但我們可能不想要它!

問(wèn)題:sayHello 是從原型鏈繼承來(lái)的,并非 person 實(shí)例自身的屬性。

二、解決方案:使用hasOwnProperty()過(guò)濾

正確做法:使用 Object.prototype.hasOwnProperty() 方法判斷屬性是否屬于對(duì)象自身。

function iterate(obj) {
  const res = [];
  for (let key in obj) {
    // ? 只保留對(duì)象自身的屬性
    if (obj.hasOwnProperty(key)) {
      res.push(key + ': ' + obj[key]);
    }
  }
  return res;
}

const result = iterate(person);
console.log(result);
// 輸出: ["name: Alice"]
// ? 成功過(guò)濾掉了原型上的 sayHello

三、hasOwnProperty原理詳解

什么是“自身屬性”(Own Property)?

  • 自身屬性:直接定義在對(duì)象實(shí)例上的屬性,如 this.name = 'Alice';
  • 繼承屬性:通過(guò)原型鏈從父級(jí)繼承來(lái)的屬性或方法,如 sayHello

hasOwnProperty()的作用

  • 檢查某個(gè)屬性是否是對(duì)象的直接屬性;
  • 返回 true 表示該屬性是自身的;
  • 返回 false 表示該屬性來(lái)自原型鏈或不存在。
person.hasOwnProperty('name');     // true  ← 自身屬性
person.hasOwnProperty('sayHello'); // false ← 來(lái)自原型
person.hasOwnProperty('toString'); // false ← 來(lái)自 Object.prototype

四、更現(xiàn)代的替代方案

雖然 hasOwnProperty 非常經(jīng)典,但現(xiàn)代 JavaScript 提供了更多選擇:

方法1:Object.keys()—— 獲取所有自身可枚舉屬性

const ownKeys = Object.keys(person);
console.log(ownKeys); // ['name']

// 結(jié)合 map 處理
const result = Object.keys(person).map(key => {
  return `${key}: ${person[key]}`;
});

優(yōu)點(diǎn):簡(jiǎn)潔,無(wú)需手動(dòng)過(guò)濾;

缺點(diǎn):只包含可枚舉屬性。

方法2:Object.getOwnPropertyNames()—— 包括不可枚舉屬性

// 添加一個(gè)不可枚舉屬性
Object.defineProperty(person, 'age', {
  value: 25,
  enumerable: false
});

console.log(Object.keys(person));           // ['name']
console.log(Object.getOwnPropertyNames(person)); // ['name', 'age']

適用場(chǎng)景:需要獲取 configurable: falseenumerable: false 的屬性。

方法3:Reflect.ownKeys()—— 最全的自身屬性列表

const obj = { a: 1 };
Object.defineProperty(obj, 'b', { value: 2, enumerable: false });
obj[Symbol('c')] = 3;

console.log(Reflect.ownKeys(obj)); // ['a', 'b', Symbol(c)]

包含:字符串鍵、Symbol 鍵、可枚舉和不可枚舉屬性。

五、hasOwnProperty的潛在風(fēng)險(xiǎn)與規(guī)避

風(fēng)險(xiǎn):對(duì)象可能重寫了hasOwnProperty

const badObj = {
  name: 'Test',
  hasOwnProperty: function () {
    return false; // 惡意重寫
  }
};

badObj.hasOwnProperty('name'); // false ? 錯(cuò)誤結(jié)果!

安全調(diào)用方式

使用 callObject.prototype.hasOwnProperty.call()

Object.prototype.hasOwnProperty.call(badObj, 'name'); // true ?
// 或
{}.hasOwnProperty.call(badObj, 'name'); // true ?

推薦在庫(kù)或通用代碼中使用這種寫法,確保健壯性。

六、完整工具函數(shù)推薦

結(jié)合你提供的 iterate 函數(shù),我們可以優(yōu)化為更健壯的版本:

function getOwnProperties(obj) {
  const res = [];
  
  // 使用安全的 hasOwnProperty 調(diào)用
  for (let key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      res.push(`${key}: ${obj[key]}`);
    }
  }
  
  return res;
}

// 或者使用現(xiàn)代 API
function getOwnPropertiesModern(obj) {
  return Object.keys(obj).map(key => `${key}: ${obj[key]}`);
}

七、總結(jié):獲取對(duì)象自身屬性的方法對(duì)比

方法是否包含原型是否包含不可枚舉是否包含 Symbol推薦場(chǎng)景
for...in + hasOwnProperty? 否? 否? 否兼容舊環(huán)境
Object.keys()? 否? 否? 否日常開發(fā),簡(jiǎn)潔
Object.getOwnPropertyNames()? 否? 是? 否需要不可枚舉屬性
Reflect.ownKeys()? 否? 是? 是全面獲取所有鍵

結(jié)語(yǔ)

“遍歷對(duì)象時(shí),for...in 是‘廣撒網(wǎng)’,hasOwnProperty 是‘精準(zhǔn)捕撈’。”

掌握如何區(qū)分自身屬性繼承屬性,是寫出高質(zhì)量 JavaScript 代碼的基本功。無(wú)論你是做數(shù)據(jù)處理、對(duì)象克隆,還是開發(fā)類庫(kù),這個(gè)知識(shí)點(diǎn)都至關(guān)重要。

記?。?/strong>

  • hasOwnProperty 過(guò)濾原型屬性;
  • 優(yōu)先使用 Object.keys() 等現(xiàn)代 API;
  • 在通用代碼中使用 Object.prototype.hasOwnProperty.call() 保證安全。

到此這篇關(guān)于一文解析JS如何準(zhǔn)確獲取對(duì)象自身的屬性的文章就介紹到這了,更多相關(guān)JS獲取對(duì)象自身屬性內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論