JS容易出现误区的操作符

类型判断

typeof

typeof操作符返回一个字符串,表示未经计算的操作数的类型。

  • typeof运算符,判断数据类型,对于基本类型,返回基本类型,对于引用类型的,不管哪一种引用类型,都返回'object'

  • typeof 除了null 返回'object',和函数返回'function',其他都能正确返回,凡是引用类型返回都是'object'

typeofnew一个构造函数生成内容的判断需要特别注意

var str = new String('String');
var num = new Number(100);

typeof str; // 返回 'object'
typeof num; // 返回 'object'

var func = new Function();

typeof func; // 返回 'function'

因此,通过typeof判断基本数据类型,也会返回不一样的结果,需要特别注意,在不确定是否是基本数据类型的场景下慎用,不过大部分场景中很少存在通过构造函数生成基本数据类型,可以使用typeof判断。

instanceof

instanceof运算符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上。通常用来判断实例是否属于一个父类型

instanceof如何实现这样的功能,语言规范里面有详细的介绍,这里截取部分:

instanceof 也可以用来判断一些内置对象类型,比如function instanceof Function, reg instanceof RegExp

Object.prototype.toString()

toString也可以做为类型判断, 返回一个类似 [Object Type]的字符串,和typeof不一样的地方在于能判断nullDateMath等内置对象。但是对于new一个构造函数,和typeof判定是一样的。

对象上指定属性判断

in

如果指定的属性在指定的对象或其原型链中,则in 运算符返回true。

重点是需要注意的是原型链存在指定的属性,也会返回true,所以in一般用来判断纯粹的对象。

Object.prototype.hasOwnProperty()

当有这种需求时,只能使用Object.prototype.hasOwnProperty()来判断,这是一个比较蛋疼的方式。

Object.hasOwn()

因此,在ES2022版本,新增了一个API,Object.hasOwn(),用来解决判断对象上是否有指定属性,不会像原型链查找

但是通过class生成类,Object.hasOwn判定为true

由规范得到,instanceof将表达式1的__proto__与表达式2的prototype进行严格相等===比较:

如果相等返回true;如果不相等,则继续循环获取前面表达式的__proto__,直到 Object.__proto__===null为止返回false。

delete

delete用于删除某个对象的属性,如果没有指向这个属性的引用,那它最终会被释放。

使用注意事项:

  • 如果你试图删除的属性不存在,那么delete将不会起任何作用,但仍会返回true

  • 如果删除属性的该对象原型链上有同名属性,delete只会删除自身属性,删除之后,对象会使用原型链上的属性。(也就是说,delete操作只会在自身的属性上起作用)

  • 任何用letconst声明的属性不能够从它被声明的作用域中删除

  • 使用var声明的属性不能从全局作用域中或者函数作用域中删除

  • 不可设置的属性不能被删除

delete删除数组对象

delete只能删除指定数组元素的对象,数组的大小不改变,删除后位置空余,显示undefined,或者其他填充值。

数组方法array.splice指定删除数组元素对象,数组大小发生变化。

Last updated