最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

“為什么遍歷一個簡單對象時,會多出一些意想不到的方法?”

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

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

一、問題背景:for...in的“陷阱”

看一個經(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  ← 這是原型上的方法,但我們可能不想要它!

問題:sayHello 是從原型鏈繼承來的,并非 person 實例自身的屬性。

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

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

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

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

三、hasOwnProperty原理詳解

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

  • 自身屬性:直接定義在對象實例上的屬性,如 this.name = 'Alice';
  • 繼承屬性:通過原型鏈從父級繼承來的屬性或方法,如 sayHello。

hasOwnProperty()的作用

  • 檢查某個屬性是否是對象的直接屬性;
  • 返回 true 表示該屬性是自身的;
  • 返回 false 表示該屬性來自原型鏈或不存在。
person.hasOwnProperty('name');     // true  ← 自身屬性
person.hasOwnProperty('sayHello'); // false ← 來自原型
person.hasOwnProperty('toString'); // false ← 來自 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):簡潔,無需手動過濾;

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

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

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

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

適用場景:需要獲取 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)險與規(guī)避

風(fēng)險:對象可能重寫了hasOwnProperty

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

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

安全調(diào)用方式

使用 callObject.prototype.hasOwnProperty.call()

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

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

六、完整工具函數(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é):獲取對象自身屬性的方法對比

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

結(jié)語

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

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

記?。?/strong>

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

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

相關(guān)文章

最新評論

高尔夫| 噶尔县| 湖南省| 个旧市| 边坝县| 黄冈市| 皮山县| 西乌| 涡阳县| 耿马| 兴化市| 九龙坡区| 沁阳市| 宜州市| 邯郸市| 黑河市| 渝北区| 沁阳市| 甘洛县| 互助| 扬中市| 卫辉市| 招远市| 汕头市| 郓城县| 德清县| 泉州市| 扎赉特旗| 宁安市| 庆城县| 于都县| 汉川市| 德钦县| 新乡县| 巴楚县| 雷波县| 黄浦区| 长沙县| 共和县| 阿城市| 永康市|