Javascript中call和apply的明白

在Javascript中,每一个函数都包括两个非继续而来的要领,
call
apply。这两个要领的用处都是在特定的作用域中挪用函数,实际上即是设置函数体内的
this对象的值。

摘自《JavaScript高等程序设计》

apply要领吸收两个参数,第一个参数是在个中运转函数的作用域,第二个是一个参数数组或许arguments对象。
call要领与apply要领作用雷同,第一个参数也雷同,区分在于,其他的参数须要逐一列出。

apply(thisArg, argArray);
call(thisArg[,arg1,arg2…]);

是运用call照样apply要看详细的状况。假如你晓得一切参数或许参数的数目不多,可以运用call;假如参数的数目不确定,或许数目很大,或许你收到的是一个数组或许是个arguments对象,则须要运用apply

下面是运用apply的一些典范例子

// 取得数组中最大的元素
var arr = [1, 8, 10, 3, 24, 89, 26];
var m = Math.max.apply(Math, arr); // m => 89

// 将类数组的对象转为数组
var arr = Array.prototype.slice.call(arguments);

事实上,callapply真正的用武之地在于,他们可以扩大函数赖以运转的作用域。

我们再来看下面的例子


var name = 'out'

var o1 = {
    name: 'hello'
};

var o2 = {
    name: 'world'
};

function sayName() {
    alert(this.name);
}

sayName.call(this); // out
sayName.call(window); // out
sayName.call(o1); // hello
sayName.call(o2); // world

前两个输出雷同,由于在全局作用域,this即为window(浏览器环境)。
剩下的两个,我们离别改变了他们的实行环境,离别指向了o1和o2,因而效果就是显现对象各自的name值。

那末,运用call和apply有什么优点呢?我们发明,一样的一个函数,当指定差别的实行环境时,会发生差别的效果,这么做的一个最大的优点就是解耦

运用call和apply,函数和对象没有强依靠关联,多个对象可以运用同一个函数,避免了资本的糟蹋,同时关于模块化编程也大有协助。

假如你依然对call和apply没有清楚的熟悉,可以试着如许明白。
我们把要领比作是东西,比方一把刀;而变量是详细的什物,比方一个苹果。我们可以运用这把刀切许多差别的苹果,在切苹果的过程当中,实际上就是改变了刀的作用对象—差别的苹果。

在上面的例子

// 将类数组的对象转为数组
var arr = Array.prototype.slice.call(arguments);

slice是一个要领,然则它是属于Array对象prototype属性一切的,在对arguments运用时,我们可以明白为借用
比方张三会砍树,即张三有砍树这个要领(至于张三有无树无所谓),而李四有树,但他却不会砍,这时候李四便可以借用张三砍树的要领来砍本身的树,写成代码就是

var zhangsan = {
   cut: function() {
        alert(this.tree);
   }
};

var lisi = {
    tree: '杨树'
};
zhangsan.cut.call(lisi); // alert('杨树')

另有一种状况是,李四本身也会砍树,然则有一天他病了,砍不动了,这时候他也可以借用张三的砍树要领砍本身的树。在代码中就是

String.prototype.toString = function() {
    return 'shit'; // 一切的String的实例对象的toString要领都被污染了,只会输出'shit'
};

var str = 'hello';

console.log(str.toString()); // 'shit'
// 这时候候怎么办呢?
// 我们须要找一个没被污染的toString要领借来用一用,比方Object(或许Array等除了String的都可以)
console.log(Object.prototype.toString.call(str)); // 输出一般的'[object String]'

到了这里,相信你对call和apply已经有了一个比较抽象的熟悉了。今后再碰到相似的题目时,无妨设想成实际中的关联,能够搅扰好久的题目就恍然大悟了。

call和apply别的一个运用就是函数的柯里化和反柯里化手艺,有兴致的可以看下面两篇文章
Javascript中风趣的反柯里化手艺
由JavaScript反柯里化所想到的

    原文作者:chshouyu
    原文地址: https://segmentfault.com/a/1190000000591832
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞