notes
  • Introduction
  • 语言
    • JS
      • JS原型到原型链
      • JS继承的实现
      • this对象
      • Promise基本概念
      • Promise实现
      • Promise实战
      • JS的EventLoop
      • JS容易出现误区的运算符
      • JS容易出现误区的操作符
      • JS深拷贝
      • JS节流与防抖
      • ES5实现原生/ES6方法
    • TS
      • 声明文件
      • 项目配置
    • CSS
      • CSS引入方式以及优先级计算
      • BFC神奇背后的原理-文摘
      • 回流reflow与重绘repaint
      • 三栏式布局
      • 垂直居中
      • 清除浮动的方法
      • 移动端适配方案
      • 纯CSS斜切角实现
      • CSS揭秘
      • 背景图片轮播
      • CSS绘制序列帧动画
      • transform实现一个多面体
    • HTML
  • ES6
  • Node.js
    • xxx
  • 前端框架
    • Vue.js
      • Vue双向数据绑定原理
      • Vue-Router原理及实现
    • React
    • AngularJS
  • 工程构建
    • Webpack
      • 01-webpack概述及背景
      • 03-webpack热更新原理
      • 04-splitChunks原理分析
      • 05-webpack工作流程
      • 07-webpack构建流程
      • 07-webpack构建流程
      • 10-webpack 如何进行性能分析
    • Gulp
    • Lint
      • ESLint
      • TSLint
    • Bable
  • 工程化
    • 模块化
    • 组件化
    • 规范化
      • 编码规范
    • 自动化
  • 运维
    • Nginx
    • GIT
    • CDN
    • VPS
    • DBA
  • 小程序
  • 跨端
  • 测试
  • 计算机技术
    • 计算机网络
      • 同源策略到前端跨域解决方案
      • TCP数据传输
      • TCP和UDP的区别
      • HTTP协议概述
      • HTTP缓存详解
      • HTTPS以及SSL建立过程
      • HTTPS的七个误解(译文)
      • cookie与Session机制区别以及Cookie SessionStorage LocalStorage异同
      • HTTP状态码Status
      • DNS原理入门
      • 网络攻击与防御
      • HTTP转发与重定向
      • 登录认证设计
    • 操作系统
      • shell脚本命令
    • Linux
      • Linux命令大全
      • vim命令
    • 浏览器
      • 浏览器内核、JS 引擎、页面呈现原理及其优化
      • 九种浏览器端缓存机制概览
      • 性能优化-网络请求方面
      • webkit解析CSS过程详解
  • 前端面试
    • 算法
Powered by GitBook
On this page
  • 类型判断
  • typeof
  • typeof对new一个构造函数生成内容的判断需要特别注意
  • instanceof
  • Object.prototype.toString()
  • 对象上指定属性判断
  • in
  • Object.prototype.hasOwnProperty()
  • Object.hasOwn()
  • delete
  • delete删除数组对象
  1. 语言
  2. JS

JS容易出现误区的操作符

类型判断

typeof

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

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

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

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

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如何实现这样的功能,语言规范里面有详细的介绍,这里截取部分:

function instance_of(L, R) {//L 表示左表达式,R 表示右表达式
  var O = R.prototype;// 取 R 的显示原型对象
  L = L.__proto__;// 取 L 的隐式原型对象
  while (true) {
    if (L === null)
        return false;
    if (O === L)// 这里重点:当 O 严格等于 L 时,返回 true 
        return true;
    L = L.__proto__;
  }
}

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

const reg = new RegExp(/e/i);
reg instanceof RegExg; // true

Object.prototype.toString()

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

var toString = Object.prototype.toString;

toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]

//Since JavaScript 1.8.5
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]

对象上指定属性判断

in

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

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

Object.prototype.hasOwnProperty()

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

let hasOwnProperty = Object.prototype.hasOwnProperty
if (hasOwnProperty.call(obj, "foo")) {
  console.log("has property foo")
}

Object.hasOwn()

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

let object = { foo: false }
Object.hasOwn(object, "foo") // true

let object2 = Object.create({ foo: true })
Object.hasOwn(object2, "foo") // false

function Person() {
}
Person.prototype.name = 'nick';
let person = new Person();

console.log('name' in person); // true
console.log(Object.prototype.hasOwnProperty(person, 'name')); // false
console.log(Object.hasOwn(person, 'name')); // false

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

class Person {
  constructor() {
    this.name = 'Nike';
  }
}

let person = new Person();
console.log('name' in person); // true
console.log(Object.prototype.hasOwnProperty(person, 'name')); // false
console.log(Object.hasOwn(person, 'name')); // true

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

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

console.log(Object instanceof Object);//true 
console.log(Function instanceof Function);//true 
console.log(Number instanceof Number);//false 
console.log(String instanceof String);//false 
console.log(Function instanceof Object);//true 
console.log(Foo instanceof Function);//true 
console.log(Foo instanceof Foo);//false

delete

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

使用注意事项:

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

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

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

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

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

delete删除数组对象

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

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

PreviousJS容易出现误区的运算符NextJS深拷贝

Last updated 3 years ago