獲取對象屬性(所有屬性、可枚舉、不可枚舉、自身屬性【非原型鏈繼承】)個數詳解


一、獲取可枚舉的屬性

方法一:for......in

方法一:Object.keys()

Object.keys() 方法會返回一個由一個給定對象的自身可枚舉屬性組成的數組,數組中屬性名的排列順序和使用 for...in 循環遍歷該對象時返回的順序一致 。

語法

Object.keys(obj)

參數

obj:要返回其枚舉自身屬性的對象。

返回值

一個表示給定對象的所有可枚舉屬性的字符串數組。

例子

// simple array
var arr = ['a', 'b', 'c']; console.log(Object.keys(arr)); // console: ['0', '1', '2'] // array like object
var obj = { 0: 'a', 1: 'b', 2: 'c' }; console.log(Object.keys(obj)); // console: ['0', '1', '2'] // array like object with random key ordering
var anObj = { 100: 'a', 2: 'b', 7: 'c' }; console.log(Object.keys(anObj)); // console: ['2', '7', '100'] // getFoo is a property which isn't enumerable
var myObj = Object.create({}, { getFoo: { value: function () { return this.foo; } } }); myObj.foo = 1; console.log(Object.keys(myObj)); // console: ['foo']

注意

在ES5里,如果此方法的參數不是對象(而是一個原始值),那么它會拋出 TypeError。在ES2015中,非對象的參數將被強制轉換為一個對象。

Object.keys("foo"); // TypeError: "foo" is not an object (ES5 code)
 Object.keys("foo"); // ["0", "1", "2"] (ES2015 code)

二、獲取可枚舉和不可枚舉屬性

Object.getOwnPropertyNames()方法返回一個由指定對象的所有自身屬性的屬性名(包括不可枚舉屬性但不包括Symbol值作為名稱的屬性)組成的數組,數組中枚舉屬性的順序與通過 for...in 循環(或 Object.keys)迭代該對

象屬性時一致。數組中不可枚舉屬性的順序未定義。

如果你想獲取一個對象的所有屬性,,甚至包括不可枚舉的,請查看Object.getOwnPropertyNames

語法

Object.getOwnPropertyNames(obj)

參數

obj:一個對象,其自身的可枚舉和不可枚舉屬性的名稱被返回。

返回值

在給定對象上找到的自身屬性對應的字符串數組。

示例

var arr = ["a", "b", "c"]; console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"] // 類數組對象
var obj = { 0: "a", 1: "b", 2: "c"}; console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"] // 使用Array.forEach輸出屬性名和屬性值
Object.getOwnPropertyNames(obj).forEach(function(val, idx, array) { console.log(val + " -> " + obj[val]); }); // 輸出 // 0 -> a // 1 -> b // 2 -> c //不可枚舉屬性
var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; }, enumerable: false } }); my_obj.foo = 1; console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]

三、獲取不可枚舉的屬性

filter()方法創建一個新數組, 其包含通過所提供函數實現的測試的所有元素。 

使用了 Array.prototype.filter() 方法,從所有的屬性名數組(使用Object.getOwnPropertyNames()方法獲得)中去除可枚舉的屬性(使用Object.keys()方法獲得),剩余的屬性便是不可枚舉的屬性了:

var target = myObject; var enum_and_nonenum = Object.getOwnPropertyNames(target); var enum_only = Object.keys(target); var nonenum_only = enum_and_nonenum.filter(function(key) { var indexInEnum = enum_only.indexOf(key); if (indexInEnum == -1) { // 沒有發現在enum_only健集中意味着這個健是不可枚舉的, // 因此返回true 以便讓它保持在過濾結果中
        return true; } else { return false; } }); console.log(nonenum_only);

提示

在 ES5 中,如果參數不是一個原始對象類型,將拋出一個 TypeError  異常。在 ES2015 中,非對象參數被強制轉換為對象 

Object.getOwnPropertyNames('foo'); // TypeError: "foo" is not an object (ES5 code)
 Object.getOwnPropertyNames('foo'); // ['length', '0', '1', '2'] (ES2015 code)

四、自身屬性【非原型鏈繼承】

使用obj.hasOwnProperty()方法,Object.prototype.hasOwnProperty()返回一個布爾值,指示對象自身屬性中是否具有指定的屬性(也就是,是否有指定的鍵),該方法會忽略掉那些從原型鏈上繼承到的屬性。

語法

obj.hasOwnProperty(prop)

參數

prop:要檢測的屬性的 String 字符串形式表示的名稱,或者 Symbol

返回值

用來判斷某個對象是否含有指定的屬性的布爾值 Boolean

示例

1、使用 hasOwnProperty 方法判斷屬性是否存在

下面的例子檢測了對象 o 是否含有自身屬性 prop

o = new Object(); o.hasOwnProperty('prop'); // 返回 false
o.prop = 'exists'; o.hasOwnProperty('prop'); // 返回 true
delete o.prop; o.hasOwnProperty('prop'); // 返回 false

2、自身屬性與繼承屬性

下面的例子演示了 hasOwnProperty 方法對待自身屬性和繼承屬性的區別:

o = new Object(); o.prop = 'exists'; o.hasOwnProperty('prop');             // 返回 true
o.hasOwnProperty('toString');         // 返回 false
o.hasOwnProperty('hasOwnProperty');   // 返回 false

備注

即使屬性的值是 null 或 undefined,只要屬性存在,hasOwnProperty 依舊會返回 true

o = new Object(); o.propOne = null; o.hasOwnProperty('propOne'); // 返回 true
o.propTwo = undefined; o.hasOwnProperty('propTwo'); // 返回 true

3、使用 hasOwnProperty 作為屬性名

JavaScript 並沒有保護 hasOwnProperty 這個屬性名,因此,當某個對象可能自有一個占用該屬性名的屬性是,就需要使用外部的 hasOwnProperty 獲得正確的結果:

var foo = { hasOwnProperty: function() { return false; }, bar: 'Here be dragons' }; foo.hasOwnProperty('bar'); // 始終返回 false // 如果擔心這種情況, // 可以直接使用原型鏈上真正的 hasOwnProperty 方法
({}).hasOwnProperty.call(foo, 'bar'); // true // 也可以使用 Object 原型上的 hasOwnProperty 屬性
Object.prototype.hasOwnProperty.call(foo, 'bar'); // true

注意,只有在最后一種情況下,才不會新建任何對象。

備注

即使屬性的值是 null 或 undefined,只要屬性存在,hasOwnProperty 依舊會返回 true

o = new Object(); o.propOne = null; o.hasOwnProperty('propOne'); // 返回 true
o.propTwo = undefined; o.hasOwnProperty('propTwo'); // 返回 true

4、獲取對象屬性的個數

var attributeCount = function(obj) { var count = 0; for(var i in obj) { if(obj.hasOwnProperty(i)) {  // 建議加上判斷,如果沒有擴展對象屬性可以不加
                count++; } } return count; }
alert(attributeCount(testObj));

或 

循環,只取自身的屬性 var count = 0; for(var i in obj){ if(obj.hasOwnProperty(i)){ count++ } } console.log(count);

參數

MDN:Object.getOwnPropertyNames()

MDN:Object.keys()

MDN:Object.prototype.hasOwnProperty()

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM