程序员让前端飞

JavaScript 对象属性的存在性

2018-09-06  本文已影响4人  打铁大师

先看一个例子

var person = {
  name:undefined
}
console.log(person.name); // undefined
console.log(person.age); // undefined

上面的例子中 person对象有一个name属性,没有age属性。但是,使用
person.name 和 person.age访问属性值时,两者的结果都是undefined。

因此我们没法通过值为undefined来判断一个对象是否有某个属性。

那么如何判断一个对象是否存在一个属性。

1. in 操作符

如果指定的属性存在对象或其原型链中,那么in操作符返回true 。

注意: in操作符判断属性的存在性,不论属性是否可枚举

举个例子:

let man = {
  speak: 'I can'
}

// 已man对象为原型创建person对象
let person = Object.create(man);
//定义person对象的name属性,该属性是person对象的自有属性
person.name='noshower';

//定义person对象的自有属性,但是'age'不可枚举,
Object.defineProperty(person, 'age', {
  enumerable: false,
  configurable: true,
  writable: true,
  value: 23
});

console.log('speak' in person);  // true
console.log('name' in person);   // true
console.log('age' in person);   // true
console.log('job' in person);   // false

因为job不存在person中,也不存在person对象的原型链上,所以结果为false。

再看个例子:

var array = new Array('a','b','c','d','e');
delete array[3];
console.log(3 in array); // false
console.log(array.length); // 5

从这个例子中看出,当删除数组的某个下标后,数组下标确实不存在了。但是没有改变数组的长度。只是该位置被空出来了而已。

2. hasOwnProperty

如果对象自身属性中存在指定的属性,那么hasOwnProperty()方法将会返回true,否则返回false。

注意:

举个例子:

let man = {
  speak: 'I can'
}

let person = Object.create(man);

person.name='noshower';

Object.defineProperty(person, 'age', {
  enumerable: false,
  configurable: true,
  writable: true,
  value: 23
});

console.log(person.hasOwnProperty('speak')); // false
console.log(person.hasOwnProperty('name')); // true
console.log(person.hasOwnProperty('age')); // true
console.log(person.hasOwnProperty('job')); // false

因为speak属性存在于原型链上,所以返回false。
因为name属性是自有属性,所以返回true。
因为age属性是自有属性,虽然该属性不可枚举,但结果还是true。
因为job属性不存在,所以没有false。

3. for...in 循环

for...in 循环用来遍历对象的可枚举属性,包括原型链上的

注意:

举个例子:

let man = {
  speak: 'I can'
}

let person = Object.create(man);

person.name='noshower';

Object.defineProperty(person, 'age', {
  enumerable: false,
  configurable: true,
  writable: true,
  value: 23
});

for(let prop in person){
  console.log(prop);   // name , speak (并不一定是这样的输出顺序)
}

其中age属性没有遍历得到,因为它是不可枚举的。

4. propertyIsEnumerable

如果一个属性是对象的自有属性(直接定义在对象上的)且该属性可枚举,那么 propertyIsEnumerable方法返回true,否则返回false。

举个例子:

let man = {
  speak: 'I can'
}

let person = Object.create(man);

person.name='noshower';

Object.defineProperty(person, 'age', {
  enumerable: false,
  configurable: true,
  writable: true,
  value: 23
});

console.log(person.propertyIsEnumerable('speak')); //false
console.log(person.propertyIsEnumerable('name')); // true
console.log(person.propertyIsEnumerable('age')); // false

5. Object.keys()

Object.keys() 方法会返回一个由给定对象的所有自身可枚举属性组成的数组。

注意:

举个例子:

let man = {
  speak: 'I can'
}

let person = Object.create(man);

person.name='noshower';

Object.defineProperty(person, 'age', {
  enumerable: false,
  configurable: true,
  writable: true,
  value: 23
});

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

6. Object.getOwnPropertyNames()

Object.getOwnPropertyNames()方法会返回一个数组,包含所有自有属性,无论它们是否可枚举。

注意:

举个例子:

let man = {
  speak: 'I can'
}

let person = Object.create(man);

person.name='noshower';

Object.defineProperty(person, 'age', {
  enumerable: false,
  configurable: true,
  writable: true,
  value: 23
});

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

7.自定义函数:getOwnInnumerablePropertyNames

getOwnInnumerablePropertyNames 只获取对象自身的所有不可枚举属性

function getOwnInnumerablePropertyNames (obj){
    //返回对象的所有自有属性,包括不可枚举的
    let props = Object.getOwnPropertyNames(obj);
    //返回对象的所有可枚举属性
    let propsEnum = Object.keys(obj); 
    // 过滤出所有不可枚举的
    return props.filter(function(key){
      return propsEnum.indexOf(key) === -1;
    })
}

参考文献

上一篇 下一篇

猜你喜欢

热点阅读