js typeof

本文详细探讨了JavaScript中typeof运算符的高级用法,包括判断函数参数、函数表达式与命名函数的区别、变量提升、立即执行函数、函数作为值传递、对象属性查找等实例。阅读本文,带你全面掌握typeof的底层原理和实际应用场景。
摘要由CSDN通过智能技术生成

参考文章:JavaScript之typeof
typeof
我们知道 typeof 可以用来判断一个值类型变量的类型,如下代码

typeof 10 // number
typeof '10' // string
typeof undefiend // undefiend
typeof true // boolean
typeof null // object

当然,上面的只是一些基础用法,下面介绍的 typeof 应用场景可能很多都没见过

function fun() {
  console.log(typeof arguments)
}
fun(1, 2) // object
fun(1) // object
fun() // object

arguments 是函数的内置对象,都是一个对象了,所以是一个复杂数据类型,所以使用 typeof arguments 返回 object

let f = function g() {
  return 23
}
console.log(typeof g()) // error,g is not defined

从报错信息可以看出来 g 并没有被定义,但是上面的代码明明有 function g。这是因为上面的代码是一个函数表达式,右边是一个函数赋值给了 f,虽然此函数有一个名字 g,但是本质上不是一个函数声明,也可以理解为 g 仅仅是一个名字而已,不起到任何作用,只是给这个匿名函数加了一个名字,真正的函数是 f,看如下代码就知道了

// 声明一个函数
function f(){
    console.log('i am function')
}
f() // i am function

let cb = function () { // 此函数是一个匿名函数,赋值给了 cb,所以cb才是一个函数
    console.lo('i am cb')
}
cb() // i am cb

var y = 1, x = y = typeof x
console.log(y) // undefiend

首先有连等符号将其从右至左拆开,即

var y = 1
y = typeof x
var x = y

var 声明的变量 x 提升,所以执行 typeof x 的时候 x的值为 undefined

(function f(f) {
  console.log(typeof f()) // number
})(function () {
  return 1
})

这个立即执行函数的实参是一个函数,返回 1,形参 f 接收到这个实参,所以此时立即执行函数内部的形参 f 是一个函数并且返回 1,所以 打印 number。
至于上面的 f 为什么不是立即执行函数本身而是立即执行函数的形参,可以看如下代码

;(function f() {
  console.log(f) // [Function: f]
})()
;(function f(f) {
  console.log(f) // 10
})(10)

;(function f() {
  function f() {
    console.log(1)
  }
  return f() // 打印2,预解析:将当前作用域的function声明都提前,后面的那个f覆盖掉了前面那个f,所以打印2
  function f() {
    console.log(2)
  }
})()

var foo = {
  bar: function () {
    return this.baz
  },
  baz: 1
}
console.log(typeof (f = foo.bar)()) // undefined

分解第七行的代码,如下

f = foo.bar
typeof f()

此时将 foo 对象的 baz 方法 赋值给了 f,此时 f 这个 函数的 this 指向为 window,并且window 没有这个 baz 属性,所以打印 undefined

var f = (function f(){ return "1"; }, function g(){ return 2; })(); 
typeof f; // number

立即执行函数里面有两个函数 f 和 g,以逗号分割。此时我们可能不太明确是哪个函数的返回值起作用。所以,可以先看如下代码

let x = (1, 2, 3, 5)
console.log(x) // 5

const fun = () => {
  return console.log('1'), 2, 3, 4, 5, 6
}
console.log(fun()) // 先打印 1,最后在打印 6

从上面的代码可以看出:当存在一个组合以逗号分割的形式存在,首先会从左到右依次计算,但这个组合的值以最后一个为准。
所以此题最后以 g 函数的为准,g 函数返回数字 2,所以 为 number

let x = 1
if (function f() {}) {
  x += typeof f
}
console.log(x) // 1undefined

if 里面的() 是不能通过 function 声明一个函数的,括号里面应该是一个表达式,在此刻声明一个 f 没有任何作用,所以 typeof f 为 undefiend。
对上述代码改进

let y = 1
if ((y = function () {})) {
  y += typeof y
}
console.log(y, typeof y) // function () {}function string

if 里面的括号是一个表达式,所以 y 被重新赋值了一个函数,函数与字符串相加会将整个函数与字符串拼接,对象和数组与字符串相加也会与字符串拼接

console.log([1, 2, , 3, 4, 5] + 'string') // 1,2,,3,4,5string
console.log({ name: 'name' } + 'string') // [object Object]string

console.log(typeof m) // undefined
var x = [typeof x, typeof y][1]
console.log(typeof typeof x) // string

由于 typeof x 和 typeof y 都是 字符串类型,值为 undefiend,所以 typeof typeof x 为 string

标题九

;(function (foo) {
  console.log(typeof foo.bar) // undefined
})({ foo: { bar: 1 } })

形参 foo 接收了一个对象,这个对象没有 bar 属性,此对象下面的 foo 对象才有一个 bar 属性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值