Code前端首页关于Code前端联系我们

为什么要写 func.apply(this,arguments)

terry 2年前 (2023-09-08) 阅读数 146 #Vue

一些不重要的废话

接续上一篇日记,通过我不断的创作努力,我终于将创客中心的一些数据变成了正数。

img01.pngimg01.png

西达蒲本

7.gif7.gif

一些重要的废话

不过我上次看起来有点紧张。抱歉,我忘了自我介绍。

9.gif9.gif

大家好,我是IT军前线军营的莫鲸上校

文本开头为

之前去掘金的时候,看到了老猿大佬将军的一篇文章。粘贴部分原代码:

function throttle(func, delay) {
    var last = 0;
    return function () {
        var now = Date.now();
        if (now >= delay + last) {
            func.apply(this, arguments);
            last = now;
        } else {
            console.log("距离上次调用的时间差不满足要求哦");
        }
    }
}
function resize(e) {
    console.log("窗口大小改变了");
}
window.addEventListener('resize', throttle(resize, 300));
 

有这样一个代码func.apply(this, arguments);。说实话,我不太明白。于是我在我1024kb存储容量的大脑中寻找相关的知识和记忆。 apply好像可以修改这个指针,而arguments好像是一个类似数组的东西……哈哈哈哈,好像没有多大帮助。

11.png11.png

既然如此,那我们就一步步来吧。

关于这个

我依稀记得大佬曾经对我说过:

只有当

时它所指向的对象才会知道这一点

事不宜迟,尝试一下。

var name = 'a', age = 0, type = 'A'
function fn () {
    console.log( this.name,'年龄是 ', this.age, '血型是 ', this.type );
}
fn() //  expected output: a 年龄是  0 血型是  A
 

在全局作用域中,调用了fn,因此this将指向全局作用域对象的窗口。

var name = 'a', age = 0, type = 'A'
function fn () {
    console.log( this.name,'年龄是 ', this.age, '血型是 ', this.type );
}
fn()
//  expected output: a 年龄是  0 血型是  A
var x = {
    name: 'XMAN',
    age: 24,
    type: this.type,
    fn: fn
}
var y = {
    name: 'YMAN',
    age: 25,
    type: 'B',
    fn: fn
}
  
x.fn() //  expected output: XMAN 年龄是  24 血型是  A
y.fn() //  expected output: YMAN 年龄是  25 血型是  B
 

其实这里调用的是同样的方法。控制台输出的内容不同的原因是它指向的对象不同。当执行x.fn()时,调用环境在x,因此指向x对象;同样,当执行 y.fn() 时,它指向 y 对象。
当然与此相关的其他情况还有很多,大家可以自行研究。 其实我怕做得太过分,我会介绍家乡的花

8.gif8.gif

关于申请、绑定、通话

先看一下MDN的描述

apply() 方法调用一个函数,该函数具有给定值和以数组(或类数组对象)形式提供的参数。

bind() 方法创建一个新函数。当调用bind()时,这个新函数的this被指定为bind()的第一个参数,其余参数作为新函数在使用时调用的参数。

call() 方法调用一个指定了该值并单独指定一个或多个参数的函数。

这三个乍一看很相似,似乎都能改变指向对象,但肯定有区别。
尝试一次:

  var name = 'a', age = 0, type = 'A'
  function fn () {
    console.log( this.name,'年龄是 ', this.age, '血型是 ', this.type );
  }
  var y = {
    name: 'YMAN',
    age: 25,
    type: 'B',
    fn: fn
  }
  fn() // expected output: a 年龄是  0 血型是  A
  fn.call(y) // expected output:  YMAN 年龄是  25 血型是  B
  fn.apply(y) // expected output:  YMAN 年龄是  25 血型是  B
  fn.bind(y)() // expected output:  YMAN 年龄是  25 血型是  B
 

可以看到绑定方式中多了一个( )。 bind 方法创建一个新函数,因此必须调用它。

再试一次:

call() 方法与 apply() 方法类似,不同之处在于 call() 方法接受参数列表,而 apply() 方法接受参数数组。

关于争吵

另外,先看看 MDN 所说的:

arguments 是一个类似数组的对象,对应于传递给函数的参数。

我举个例子:

  function testArguments() {
    console.log(arguments);
    // expected output: Arguments(3) ["a", "b", "c", callee: ƒ, Symbol(Symbol.iterator): ƒ]
    
    console.log('arguments.length :>> ', arguments.length);
    // expected output: arguments.length :>>  3
    
    console.log(arguments[0])
    // expected output: a
    
    arguments.push('d')
    // expected output: arguments.push is not a function
  }
  testArguments('a','b','c')
 

从上面可以看出,arguments 是一个由传递给函数的参数组成的类数组,有长度,也可以通过index 来获取对应的数据,但它没有像push 这样的方法。其实也是可以想象的。毕竟是别人的领域,怎么能用来论据呢?

总结

通过我们不懈的努力,终于找到了这行代码的相关知识func.apply(this, arguments);。所以答案就在眼前...

12.jpg12.jpg

まますまますまています(等一下),我好像还出不来,我再想想……

6.jpg6.jpg

说一下我自己的一些看法:通过app改变了this的方向,this应该指向窗口;当然,我认为参数更重要,因为函数是传入的,也就是说,它不是。如果它是固定函数,则其参数可能不固定,并且arguments 可能会向 func 传递不确定数量的参数。这样你就不用担心它有什么功能,需要什么参数。

终于

这是我第二次写文章了。如果有什么不对的地方,请指正。 我当然不会改变。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

上一篇:JS声明的推广 下一篇:了解事件

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门