JS基础类型的包装问题

67 阅读2分钟

JS基础类型的包装问题

请问以下各个log输出什么?为什么会这样输出?

function test() {
  console.log(this);
  console.log(arguments);
}
​
const obj = {
fn: test
}
​
test(1, 2, 3);
obj.fn(1, 2, 3);
test.call(obj, 1, 2, 3);
obj.fn.call(1, 2, 3);

this 关键字是函数运行时自动生成的一个内部对象,只能在函数内部使用,总指向调用它的对象.参考链接

arguments关键字是函数内部的参数对象,生成函数作用域自动拥有的变量. 参考链接

call可以显式绑定this的指向.参考链接

1. test(1, 2, 3)

在全局作用域中直接调用函数,相当于 window.test(),参数对象则就是为当前传入的参数对象

因此:

test(1, 2, 3);
// this => window
// arguments => Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]

2. obj.fn(1, 2, 3)

this总是指向调用他的对象,因此obj.fn()thisobj; 参数对象arguments则为传入的参数对象

因此:

obj.fn(1, 2, 3);
// this => obj
// arguments => Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]

3. test.call(obj, 1, 2, 3)

call可以显式更改this的指向, 具体流程可入下列代码

test.call(obj, 1, 2, 3)
    => obj[Symbol] = test
    => obj[Symbol](1, 2, 3)
    => delete obj[Symbol]

因此:

test.call(obj, 1, 2, 3)
// this => obj
// arguments => Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]

4. obj.fn.call(1, 2, 3)

当看到call方法后面的上下文对象this位置放得是 1, 是一个数值,是不是有点懵,特别是面试的时候;

千万别慌我们冷静分析:

  1. obj.fn.call(1, 2, 3)就是一个函数,然后调用了 call方法

    obj.fn.call(1, 2, 3) => test.call(1, 2, 3)
    
  2. 按call的实现思路

    test.call(1, 2, 3)
        => (1)[Symbol] = test
        => (1)[Symbol](1, 2, 3)
        => delete (1)[Symbol]
    

    疑惑: 可是1是一个数值啊,怎么可能有方法呢?

冷知识

JS的包装类型: 原始数据类型,在调用属性和方法时,js会在后台隐式的将基本类型转换成对象

// 场景: 保留1位小数
3.1415926.toFixed(1)

image-20230306152823742.png

很明显,当使用一个数值的时候,我们直接在后面去取对应的属性会自动给我们提示API;我们在使用数值的时候可能会潜意识使用它的API,但是却没有知其所以然,在看到obj.fn.call(1, 2, 3)这个例子的时候自然会吃瘪。

MDN valueOf方法参考链接

该方法通常是由 JavaScript 引擎在内部隐式调用的,而不是由用户在代码中显式调用的。

因此放在 this参数位置的1其实是一个Number类型的对象,所以很容易得出结果

obj.fn.call(1, 2, 3) => test.call(1, 2, 3)
​
test.call(1, 2, 3)
    => (1)[Symbol] = test
    => (1)[Symbol](2, 3)
    => delete (1)[Symbol]
​
obj.fn.call(1, 2, 3)
// Number{1}
// arguments => Arguments(2) [2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]

总结

通过这个例子,我们即能掌握 this的指向问题,arguments是什么,call的基本使用以及JS的包装类型;学到了给我点个赞吧,嘻嘻嘻!