JS 变量类型

JS 中有 6 种原始值,分别是:

  1. boolean
  2. number
  3. string
  4. undefined
  5. symbol
  6. null
  7. object

引用类型:

  1. 对象
  2. 数组
  3. 函数

JS 中使用 typeof 能得到哪些类型?

其中一个奇怪的 null,虽然是基本变量,但是因为设计的时候null是全 0,而对象是000开头,所以有这个误判。

  1. boolean
  2. number
  3. string
  4. undefined
  5. symbol
  6. object
  7. function
  8. bigint

instanceof 能正确判断对象的原理是什么?

判断一个对象与构造函数是否在一个原型链上

function instanceofs(a, b) {
  if (a == null) return false
  if (a.__proto__ == b.prototype) {
    return true
  }
  return instanceofs(a.__proto__, b)
}
instanceofs(p1, Person)

const Person = function () {}
const p1 = new Person()
p1 instanceof Person // true

var str = 'hello world'
str instanceof String // false

var str1 = new String('hello world')
str1 instanceof String // true

实现一个类型判断函数

  1. 判断 null
  2. 判断基础类型
  3. 使用Object.prototype.toString.call(target)来判断引用类型

注意: 一定是使用call来调用,不然是判断的 Object.prototype 的类型 之所以要先判断是否为基本类型是因为:虽然Object.prototype.toString.call()能判断出某值是:number/string/boolean,但是其实在包装的时候是把他们先转成了对象然后再判断类型的。 但是 JS 中包装类型和原始类型还是有差别的,因为对一个包装类型来说,typeof 的值是 object

/**
 * 类型判断
 */
function getType(target) {
  //先处理最特殊的Null
  if (target === null) {
    return 'null'
  }
  //判断是不是基础类型
  const typeOfT = typeof target
  if (typeOfT !== 'object') {
    return typeOfT
  }
  //肯定是引用类型了
  const template = {
    '[object Object]': 'object',
    '[object Array]': 'array',
    // 一些包装类型
    '[object String]': 'object - string',
    '[object Number]': 'object - number',
    '[object Boolean]': 'object - boolean',
  }
  const typeStr = Object.prototype.toString.call(target)
  return template[typeStr]
}

"a common string"为什么会有 length 属性

通过字面量的方式创建:var a = 'string';,这时它就是基本类型值; 通过构造函数的方式创建:var a = new String('string');这时它是对象类型。

基本类型是没有属性和方法的,但仍然可以使用对象才有的属性方法。 这时因为在对基本类型使用属性方法的时候,后台会隐式的创建这个基本类型的对象,之后再销毁这个对象

如何判断一个数据是不是 Array

  • Array.isArray(obj)
    • ECMAScript 5 种的函数,当使用 ie8 的时候就会出现问题。
  • obj instanceof Array
    • 当用来检测在不同的 window 或 iframe 里构造的数组时会失败。这是因为每一个 iframe 都有它自己的执行环境,彼此之间并不共享原型链,所以此时的判断一个对象是否为数组就会失败。此时我们有一个更好的方式去判断一个对象是否为数组。
  • Object.prototype.toString.call(obj) == '[object Array]'
    • 这个方法比较靠谱
  • obj.constructor === Array
    • constructor 属性返回对创建此对象的函数的引用

undefined 可被赋值

在 ES3 中(Firefox4 之前),window.undefined 就是一个普通的属性,你完全可以把它的值改变成为任意的真值,但在 ES5 中((Firefox4 之后),window.undefined 成了一个不可写,不可配置的数据属性,它的值永远是 undefined。

var undefined = 1
alert(undefined) // chrome: undefined,  ie8: 1

不管是标准浏览器,还是老的 IE 浏览器,在函数内部 undefined 可作为局部变量重新赋值

function fn() {
  var undefined = 100
  alert(undefined) //chrome: 100,  ie8: 100
}
fn()

有时候我们需要判断一个变量是不是 undefined,会这样用

if (str === undefined) {
  console.log('I am empty')
}

但假如 str 这个变量没声明就会出现报错,用下面的方式会更好一些

if (typeof str === 'undefined') {
  console.log('I am better')
}

有时候我们会看到这种写法

if (str === void 0) {
  console.log('I am real undefind')
}

那是因为 「void 0」的执行结果永远是「undefined」, 即使在某些老旧浏览器 或者在某个函数中 undefined 被重新赋值,我们仍然可以通过void 0得到真正的 undefined

results matching ""

    No results matching ""