suchen

Heim  >  Fragen und Antworten  >  Hauptteil

javascript – Fragen zu apply() und call()

function sum(num1,num2) {
    return num1 + num2;
}
function callSum1(num1,num2) {
    return sum.apply(this,arguments);
}
function callSum2(num1,num2) {
    return sum.apply(this,[num1,num2]);
}

alert(callSum1(10,10));
alert(callSum2(10,10));

//call()例子就省略了

Frage:
1.sum.apply(this,arguments) bezieht sich auf das Objekt sum, das die apply-Methode aufruft. Dies bezieht sich auf callSum() und sum(), die beide im gleichen Bereich ausgeführt werden.
2. Welchen Anwendungswert haben apply() und call() im Projekt?

滿天的星座滿天的星座2707 Tage vor1167

Antworte allen(5)Ich werde antworten

  • 淡淡烟草味

    淡淡烟草味2017-07-05 11:03:57

    楼上写的真复杂:)

    听我讲讲,题主疑惑的地方
    1:

    function callSum1(num1,num2) {
        return sum.apply(this,arguments);    // 这里的arguments和下面的[num1,num2]是同一个意思
    }
    function callSum2(num1,num2) {
        return sum.apply(this,[num1,num2]);
    }

    arguments 是一个类似数组的对象, 对应于传递给函数的参数。arguments对象是所有函数中可用的局部变量。你可以使用arguments对象在函数中引用函数的参数。

    PS:this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象

    2、call和apply应用价值(存在的意义):

    作用都是为了改变函数运行时上下文而存在的。 即改变函数体内部this的指向
    "说白点,a有xx方法,b没有。b可以问a借!"(这tm不就是继承嘛~)

    call和apply不同点:

    接受参数方式不一样。

    如下:
    call接受的是连续参数,apply接受的是数组参数。
    A.call(this, a,b,c,d)
    A.apply(this, [a,b,c,d])

    一个传送门:http://www.jianshu.com/p/a7b1...

    Antwort
    0
  • typecho

    typecho2017-07-05 11:03:57

    1. arguments是function内置属性之一,表示函数数组对象,即 callSum1里的arguments 指代 num1和num2
      https://developer.mozilla.org...

    2. apply 跟 call的价值在于,能够使得指定函数里面的this指向特定的对象上,举个例子,我们用document.querySelectorAll()获取的dom其实是一个类数组对象,非数组,如果想要用数组的方法时,可以是这样

    var doms = document.querySelectorAll('p');
    [].forEach.call(doms, function(e){
        //遍历元素
    });

    而apply 跟call主要区别在于参数格式,这个建议题主翻翻MDN。

    Antwort
    0
  • 巴扎黑

    巴扎黑2017-07-05 11:03:57

    1.sum.apply(this,arguments)说的是对象sum调用apply方法,this指的是callSum()与sum()都是同一个作用域运行,arguments指的就是”sum1,sum2”?

    2.apply()与call()的在项目中应用价值是什么呢?

    针对 1 执行结果两个都返回 20 20

    sum.apply(this,arguments) 指的是用apply来调用sum 指定sum执行的时候的this为现在的这个this 后面的arguments是参数列表 是一个类数组对象,你可以简单地当成数组对待。

    sum.apply(this,[num1, num2]) 与上面类似。

    关于arguments,发一张截图你可能就会有感性的认识了


    以下是针对第二点的回答

    钦点this

    比较好理解 就是改变 this 指向 比如在 ajax 请求的 success 回调的时候

    比如在vue开发的时候 如果没有箭头函数 得要用 var that = this 这样暂存 this。 如果可以钦点this就没这些问题

    举个栗子

    function sayName(){
        console.log(this.name); 
    }
    
    var xiao_ming = {
        name: '小明妹妹'
    }
    
    // 钦点 this 
    sayName.call(xiao_ming); 

    把类数组对象转化成真丶数组

    arguments 通过类数组对象的形式 保存着函数的参数列表 。

    function sumAll(){
        var argu = Array.prototype.slice.call(arguments); 
        
        // 从 0 开始积、每次 sum + cur 作为下次的 sum 
        return argu.reduce((sum, cur) => sum + cur, 0); 
    }

    其实从这里可以窥见:执行 slice 只需要对象具备 length 正确的下标 就可以正常执行 并返回结果。

    因为数组的很多方法都可以用在类数组对象上,因此类数组对象很多时候确实可以被认为就是数组。

    // 声明一个类数组对象 
    var a = {
        0: 'hello',
        1: 'seg',
        2: 'ment',
        3: 'fault',
        length: 4
    }
    
    // forEach 
    Array.prototype.forEach.call(a, elem => console.log(elem)); 
    // => 遍历打印
    
    // reduce 
    var helloSF = Array.prototype.reduce.call(a, (acc, cur) => acc + cur + ' ', ''); 
    console.log(helloSF); 
    // => 
    // "hello seg ment fault "
    


    还可以做的更像数组

    var a = {
        0: 'hello',
        1: 'seg',
        2: 'ment',
        3: 'fault',
        length: 4
    }
    
    a.__proto__ = Array.prototype; 
    a.forEach(e => console.log(e)); 
    Array.prototype.reduce.call(a, (acc, cur) => acc + cur + ' ', ''); 

    Object Really Like Array

    实现偏函数 Partial Function

    跟数学上的偏函数类似,比如:

    函数 f(x, y) = x + y
    如果令 y = k 那么可以得到偏函数 f(x, k) = x + k
    ( 或者这样可能更好理解: f(x, 4) = x + 4 )

    一般都是用 bind 来实现偏函数的。 不过 apply 和 call 和 bind 应该集中的讲讲。

    function logger(type){
        return console.log.bind(console, type); 
    }

    用 apply 实现上述 logger 就是:

    function logger2(type){
        return function(){
            var argu = Array.prototype.slice.call(arguments);  
            argu.unshift(type); 
            console.log.apply(console, argu); 
        }
    }

    高阶函数和柯里化

    高阶函数一般指的是返回值是函数或者其参数是函数的函数。

    setTimeout 是个很好的例子 它接受一个参数(一般是函数) 然后在一定时延后执行它。
    不过传进去之后一般 this 就指向了 全局对象 window 如果想要钦点 this 就得用 call apply 和 bind

    上面的 logger2 就做到了这点 返回了一个函数出去


    关于柯里化 先看函数 add

    function add(x, y){
        return a + b; 
    }
    
    add(1, 2); 
    // => 
    // 3 

    如果参数能一个一个的传 传到第二个的时候就得出结果:

    var add1 = add(1); 
    add1(2); 
    // => 3 
    
    add(3)(4); 
    // => 7

    第一次执行返回了一个函数,如果把 add 看成是数学意义上的函数 那就是 f(x, y) = x + y 我们执行了一次 add(1) 得到 add1 其实就是令 x = 1 了,于是得到偏函数

    f(1, y) = 1 + y

    第二次再执行 y 会得到实际值 算式就可以算出结果出来。

    这其实是一步步消元的过程。


    有什么用的?

    我在函数式编程方面也才初学,还没领会到精髓,唯一对柯里化体会的用处是 惰性求值
    刚刚的运算在参数给齐之前不会运行 等到参数够了就会算出结果。


    大半夜不睡觉刷sf 只能想到这些了。。。。

    Antwort
    0
  • 过去多啦不再A梦

    过去多啦不再A梦2017-07-05 11:03:57

    手动设置this作用域。

    Antwort
    0
  • 迷茫

    迷茫2017-07-05 11:03:57

    百度一下你就知道。

    Antwort
    0
  • StornierenAntwort