in 操作符

110 阅读2分钟

The in operator returns true if the specified property is in the specified object or its prototype chain.

in 操作符不仅会在指定对象的属性中查找,也会在其原型链中查找,找到则返回 true

语法

prop in object
#prop in object

#prop 表示类的私有属性, in 的右边必须为 Object

示例

Basic usage

const trees = ["redwood", "bay", "cedar", "oak", "maple"];
0 in trees; // returns true
3 in trees; // returns true
6 in trees; // returns false
"bay" in trees; // returns false (you must specify the index number, not the value at that index)
"length" in trees; // returns true (length is an Array property)
Symbol.iterator in trees; // returns true

You must specify an object on the right side of the in operator. For example, you can specify a string created with the String constructor, but you cannot specify a string literal.

console.log('length' in new String('apple')) // true
console.log('length' in 'apple') // TypeError: Cannot use 'in' operator to search for 'length' in apple

Using the in operator with deleted or undefined properties

const trees = ["redwood", "bay", "cedar", "oak", "maple"];
delete trees[3];
console.log(3 in trees) // returns false

有点奇怪,打印出来看一下

console.log(trees) // [ 'redwood', 'bay', 'cedar', <1 empty item>, 'maple' ]

trees[3] 赋值为 undefined

trees[3] = undefined
console.log(trees) // [ 'redwood', 'bay', 'cedar', undefined, 'maple' ]
console.log(3 in trees) // true

Inherited properties

const ages = { alice: 18, bob: 27 };

console.log("hasOwnProperty" in ages) // true

如果你只想检查Object中的key,可以使用Object.hasOwn

console.log(Object.hasOwn(ages, "hasOwnProperty")) // false

branded checks

class Person {
  #age; // 私有属性
  constructor(age) {
    this.#age = age;
  }
  static isPerson(o) {
    return #age in o; // branded check
  }
  ageDifference(other) {
    return this.#age - other.#age;
  }
}

const p1 = new Person(20);
const p2 = new Person(30);
console.log(p1.ageDifference(p2)); // -10
console.log(Person.isPerson(p1)); // true

if (Person.isPerson(p1) && Person.isPerson(p2)) {
  console.log(p1.ageDifference(p2)); // -10
}

for...in 与 in

const trees = ["redwood", "bay", "cedar", "oak", "maple"];
"length" in trees; // returns true (length is an Array property)
Symbol.iterator in trees; // returns true
for(let key in trees) {
    console.log(key) // 0 1 2 3 4 
}

lengthSymbol.iterator 去哪了。先看下 for...in 的定义:for...in 语句以任意顺序迭代一个对象的除Symbol以外的可枚举属性,包括继承的可枚举属性。

for...in 不会迭代 Symbol, 再看下 length 是不是可枚举属性

console.log(Object.getOwnPropertyDescriptor(trees, 'length')) 
// { value: 5, writable: true, enumerable: false, configurable: false }

length is an Array property, but is not enumerable.