"探秘JavaScript:类型判断的奇妙世界(二)"

146 阅读3分钟

引言

在上一篇内容里,我们介绍了JavaScript类型判断里的 typeofinstanceof 方法

"探秘JavaScript:类型判断的奇妙世界(一)"

在结尾处我们提到了 typeofinstanceof 都有一些不完美的地方,今天我们将来介绍一个完美判断类型的方法 Object.prototype.toString.call()

Object.prototype.toString.call()

话不多说,我们先上代码看效果

let str = 'hello'//String
let num = 123 //number
let flag = false //boolean
let und = undefined //undefined
let nu = null //null
let big = 123n//bigInt
let s = Symbol('hello')//Symbol 用来定义独一无二的值
let s2 = Symbol("hello")

console.log(Object.prototype.toString.call(str));
console.log(Object.prototype.toString.call(num));
console.log(Object.prototype.toString.call(flag));
console.log(Object.prototype.toString.call(und));
console.log(Object.prototype.toString.call(nu));
console.log(Object.prototype.toString.call(big));
console.log(Object.prototype.toString.call(s));

运行结果:

image.png

我们可以看到 Object.prototype.toString,call() 方法确实完美地将各种变量的类型给判断出来了

细心的小伙伴可能就会发现了,传入的属性的类型确实判断出来了,可是前面的object又是一个什么东西呢? 那么我们不得不提到Object.prototype.toString 方法了

Object.prototype.toString

Object.prototype.toString 是 JavaScript 中的一个方法,它返回一个表示对象的字符串。默认情况下,toString() 方法被每个 Object 对象继承。如果此方法在自定义对象中未被覆盖,toString() 返回 "[object type]",其中 type 是对象的类型。 那么我们可以知道,toString()方法在没有被重写的情况下返回"[object t "[object type]"ype]",那"toString()"方法又由 Object.prototype 调用,那么返回的就是 "[object object]"

那么我们的Object.prototype.toString.call() 方法又是怎么样判断出数据类型的呢?那么就要说到我们的call()方法了

call()

我们先来看call()方法做了什么

Function.prototype.myCall = function(context){
    if(!(this instanceof Function)){
        throw new TypeError('myCall is not a function')
    }
    //Array.from(arguments) 将类数组转化为数组
    let args = Array.from(arguments).slice(1)//arguments.slice(1)
    context.fn = this
    //...args 将数组中的数解构出来
    let res = context.fn(...args) // 触发this隐式绑定规则
    delete context.fn//如果不删除 执行 console.log(obj)时会多出一个 fu:foo
    return res
}

mycall()方法:

  1. 首先,它检查 this 是否是一个函数,如果不是,它抛出一个类型错误。这是因为 call 只能被函数调用。
  2. 然后,它将 arguments 对象转换为数组,并移除第一个元素(即上下文对象 context)。arguments 对象是一个类数组,包含了函数被调用时传入的参数。
  3. 它将 context 对象的 fn 属性设置为 this (即当前函数)。这是为了让 context 成为函数的调用者,从而改变函数内部的 this 指向。
  4. 使用扩展运算符 ...args 执行函数并获取结果。...args 会将数组中的元素解构出来作为单独的参数传入函数。
  5. 删除 context.fn 属性。这是为了避免在使用 context 对象时,看到一个额外的、不必要的 fn 属性。
  6. 返回执行函数得到的结果。

这就是call()方法做的工作

结尾

javaScript的类型判断讲到这里就告一段落了,相信同学们已经掌握类型判断的使用了! 今天的分享就到此结束了,关注我,获取更多小知识 ~~