js 小技巧:in 操作符的两种使用方式

53 阅读2分钟

我正在参加「掘金·启航计划」

in 操作符有两种使用方式:

  1. 单独使用

    in 操作符会在通过对象能访问给定属性时返回 true,无论该属性是存在于实例中还是原型中。

    function Person(){}
    
    Person.prototype.name = 'nick'
    
    var person1 = new Person()
    
    alert(person1.hasOwnProperty('name')) // false 只判断实例属性
    alert('name' in person1) // true
    

    由此可知,同时使用 hasOwnProperty()方法和 in 操作符,就可以确定该属性到底是存在于对象中,还是存在于 原型中。由于 in 操作符只要通过对象能够访问到属性就返回 true, hasOwnProperty()只在属性存在于
    实例中时才返回 true,只要 in 操作符返回 true 而 hasOwnProperty()返回 false,就可以确定属性是原型中的属性。

function hasPrototypeProperty(object, name){  
    return !object.hasOwnProperty(name) && (name in object);  
}
  1. 在 for-in 循环中使用

for-in 循环,返回的是所有能够通过对象访问的、可枚举的属性。也就是说只遍历可枚举属性。像 Array 和 Object 使用内置构造函数所创建的对象都会继承自 Object.prototype 和 String.prototype 的不可枚举属性,这种是无法遍历的

JS for in 循环是为遍历对象而创建的,虽然也可以遍历数组,但是并不推荐,若要遍历数组,可以使用 for 循环或者 for of循环。

for (let key in value) {
  //do something here
}

要取得对象上所有可枚举的实例属性,可以使用 Object.keys() 方法

function Person(){  
}  
Person.prototype.name = "Nicholas";  
Person.prototype.age = 29;  
Person.prototype.job = "Software Engineer";  
Person.prototype.sayName = function(){  
alert(this.name);  
};  
var keys = Object.keys(Person.prototype);  
alert(keys); //"name,age,job,sayName"  
var p1 = new Person();  
p1.name = "Rob";  
p1.age = 31;  
var p1keys = Object.keys(p1);  
alert(p1keys); //"name,age"

如果想要获取所有实例属性,无论它是否可枚举,还可以使用 Object.getOwnPropertyNames() 方法。

var keys = Object.getOwnPropertyNames(Person.prototype);  
alert(keys); //"constructor,name,age,job,sayName"

可见返回结果中包含了不可枚举的 constructor 属性。

Object.keys()和 Object.getOwnPropertyNames()方法都可以用来替代 for-in 循环。