原文: The JavaScript `in` Operator Explained With Examples
在学习 JavaScript(或任何其他编程语言)时,你首先会遇到的话题之一是运算符。
最常见的运算符是算术、逻辑和比较运算符。但是你知道 JavaScript 有一个 in
运算符吗?
如果你不知道,不要着急。我最近在谷歌上搜索一个问题的解决方案时才发现了它。
在这篇文章中,你将了解到 JavaScript in
运算符的确切作用、何时使用它,以及如何使用它。
JavaScript in 操作符是什么
JavaScript in
操作符用于检查一个对象或其继承的属性(换句话说,它的原型链)中是否存在一个指定的属性。如果指定的属性存在,in
操作符返回 true
。
JavaScript 原型链是实现对象或对象实例访问原本不属于它们的属性和方法。这些对象继承了在其构造函数或原型中定义的属性和方法,可以通过它们的 __proto__
属性来访问。
本文假设你对什么是对象、如何创建对象、它们的用途以及 JavaScript 的继承如何运行有基本的了解。如果你不知道,MDN 上的这篇文章应该会有帮助。(译者注:也可以参考 freeCodeCamp 专栏的这篇文章。)
什么时候使用 JavaScript in 操作符
为了验证一个对象是否存在一个属性
const car = {
make: 'Toyota',
model:'Camry',
year: '2018',
start: function() {
console.log(`Starting ${this.make} ${this.model}, ${this.year}`);
}
}
'make' in car // 返回 true.
'start' in car // 返回 true.
'Toyota' in car // 返回 false. 'Toyota' 不是一个属性名称,而是一个值
为了验证一个属性是否被一个对象所继承
让我们使用 ES6 class 语法来构造对象。这也适用于构造函数:
class Car {
constructor(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
start() {
console.log(`Starting ${this.make} ${this.model}, ${this.year}`);
}
}
const toyota = new Car('Toyota', 'Camry', '2018');
'start' in toyota;
/* 返回 true,因为 toyota 是 Car 对象构造函数的一个实例。因此,toyota 对象继承了 Car 构造函数的所有属性。*/
'toString' in toyota;
/* 返回 true。toString 是 Object 类型的一个方法属性,Car 构造函数是该类型的一个实例。*/
验证一个数组上是否存在一个索引/键
你可能想知道,既然我们确定了 JavaScript in
操作符可以用于对象,我们是否也可以将其用于数组呢?
嗯,数组实际上是 Object
类型的一个原型(实例)。事实上,JavaScript 中的所有东西都是 Object
类型的一个实例。
这听起来很疯狂,但让我们在浏览器的控制台中运行一个简单的程序来确认。
首先,定义一个数组,用 instanceof
操作符确认它是否是 Object
类型的实例:
const number = [2, 3, 4, 5];
number instanceof Object // 返回 true
理解了吗?在控制台中输入 number
并按回车键,然后打开输出。
你会注意到一个属性列表,其中一个是 __proto__
,指向 Array
。把它打开,然后往下看,我们会看到另一个 __proto__
属性,其值为 Object
。
这表明 number
数组是一个 Array
类型的实例,而 Array
类型是一个 Object
类型的实例。
现在,回到使用 in
操作符的问题上:
const number = [2, 3, 4, 5];
3 in number // 返回 true.
2 in number // 返回 true.
5 in number // 返回 false,因为 5 不是数组上现有的索引,而是一个值;
'filter' in number
/* 返回 true,因为 filter 是 Array 类型的方法属性,number 数组是其实例。number 数组继承了 filter 属性。*/
验证一个 HTML 元素上是否存在一个属性
在 Kirupa 的文章《检查你是否在一个支持触摸的设备上》中,他强调了这个功能:
function isTouchSupported() {
var msTouchEnabled = window.navigator.msMaxTouchPoints;
var generalTouchEnabled = "ontouchstart" in document.createElement("div");
if (msTouchEnabled || generalTouchEnabled) {
return true;
}
return false;
}
通过检查 window.navigator.msMaxTouchPoints
和 ontouchstart
属性是否存在,如果你在一个支持触摸的设备上,该函数返回 true
;如果你在一个不支持触摸的设备上,则返回 false
。这些属性只存在于支持触摸的设备上。
相当简单明了!
让我们把注意力集中在强调的那一行。还记得我们是如何确定,如果指定的属性存在于一个对象中,in
操作符就会返回 true
吗?在 JavaScript 中使用的 HTML 元素实际上成为 Object
类型的实例,因此被称为“文档对象模型”或 DOM。
当然,如果没有某种证明,你可能不会相信我。像以前一样,让我们在控制台中输入一些命令。
创建一个 div
元素,用 console.dir()
列出其属性:
const element = document.createElement('div');
console.dir(element);
然后你会看到控制台中列出 div
元素及其属性。
打开下拉菜单,你会注意到它有一个 __proto__
属性是 HtmlDivElement
。打开它,你会发现另一个 __proto__
属性是 HtmlElement
,然后是 Element
、Node
、Eventtarget
,最后是 Object
。
并运行:
element instanceof Object
这将返回 true
,表明 div
元素是 Object
类型的一个实例,这就是为什么可以对其使用 in
操作符。
总结
你已经了解了不太流行的 JavaScript in
操作符,它被用来验证对象或 Object
类型实例上的属性是否存在。这在编写验证逻辑时应该会很方便。
如果你喜欢这篇文章,你一定会喜欢我博客 codewithlinda.com 上的其他文章。在那里,我发布了对初学者友好的关于前端开发的文章。