xml地图|网站地图|网站标签 [设为首页] [加入收藏]

深入浅出妙用

来源:http://www.ccidsi.com 作者:呼叫中心培训课程 人气:85 发布时间:2019-05-02
摘要:深刻浅出妙用 Javascript 中 apply、call、bind 2015/09/24 · JavaScript· 4 评论 ·apply,bind,call 本文作者: 伯乐在线 -chokcoco。未经小编许可,禁止转发! 应接参与伯乐在线 专辑小编。 那篇小说实

深刻浅出妙用 Javascript 中 apply、call、bind

2015/09/24 · JavaScript · 4 评论 · apply, bind, call

本文作者: 伯乐在线 - chokcoco 。未经小编许可,禁止转发!
应接参与伯乐在线 专辑小编。

那篇小说实在是很难下笔,因为网络有关小说成千上万。

巧合的是后天看到阮老师的一篇小说的一句话:

“对自己来讲,博客首先是壹种知识管理工具,其次才是流传工具。作者的手艺文章,首要用来收十自个儿还不懂的学识。作者只写那个自个儿还从未完全精晓的事物,这么些自个儿明白的事物,往往未有动力写。炫彩未有是自己的主张,好奇才是。”

对此那句话,无法扶助越来越多,也让自身下决心好好写那篇,英特网小说虽多,多数复制粘贴,且晦涩难懂,小编希望能够通过那篇文章,能够清楚的升官对apply、call、bind的认知,并且列出部分它们的妙用加深回忆。

   apply、call

在 javascript 中,call 和 apply 皆感觉了转移有些函数运转时的上下文(context)而存在的,换句话说,正是为了转移函数体内部 this 的指向。

JavaScript 的一大特点是,函数存在「定义时上下文」和「运营时上下文」以及「上下文是足以改变的」这样的概念。

先来1个板栗:

JavaScript

function fruits() {} fruits.prototype = { color: "red", say: function() { console.log("My color is " this.color); } } var apple = new fruits; apple.say(); //My color is red

1
2
3
4
5
6
7
8
9
10
11
function fruits() {}
 
fruits.prototype = {
    color: "red",
    say: function() {
        console.log("My color is " this.color);
    }
}
 
var apple = new fruits;
apple.say();    //My color is red

然则假诺我们有2个对象banana= {color : “yellow”} ,大家不想对它再也定义 say 方法,那么我们能够透过 call 或 apply 用 apple 的 say 方法:

JavaScript

banana = { color: "yellow" } apple.say.call(banana); //My color is yellow apple.say.apply(banana); //My color is yellow

1
2
3
4
5
banana = {
    color: "yellow"
}
apple.say.call(banana);     //My color is yellow
apple.say.apply(banana);    //My color is yellow

因此,能够看看 call 和 apply 是为着动态退换 this 而出现的,当二个 object 未有有些方法(本栗子中banana未有say方法),不过其余的有(本栗子中apple有say方法),我们得以依靠call或apply用任何对象的秘诀来操作。

apply、call 的区别

对此 apply、call 贰者来讲,成效完全一致,只是接受参数的方法不太雷同。比如,有3个函数定义如下:

JavaScript

var func = function(arg1, arg2) { };

1
2
3
var func = function(arg1, arg2) {
 
};

就能够通过如下情势来调用:

JavaScript

func.call(this, arg1, arg2); func.apply(this, [arg1, arg2])

1
2
func.call(this, arg1, arg2);
func.apply(this, [arg1, arg2])

中间 this 是你想钦赐的上下文,他得以是其余三个 JavaScript 对象(JavaScript 中漫天皆对象),call 必要把参数按梯次传递进入,而 apply 则是把参数放在数组里。

JavaScript 中,有个别函数的参数数量是不固定的,因而要说适用规则的话,当您的参数是强烈精通数据时用 call 。

而不明确的时候用 apply,然后把参数 push 进数组传递进入。当参数数量不确定时,函数内部也足以通过 arguments 这么些数组来遍历全体的参数。

为了加固深化纪念,上面列举部分常用用法:

一、数组之间追加

JavaScript

var array1 = [12 , "foo" , {name "Joe"} , -2458]; var array2 = ["Doe" , 555 , 100]; Array.prototype.push.apply(array1, array2); /* array1 值为 [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */

1
2
3
4
var array1 = [12 , "foo" , {name "Joe"} , -2458];
var array2 = ["Doe" , 555 , 100];
Array.prototype.push.apply(array1, array2);
/* array1 值为  [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */

②、获取数组中的最大值和最小值

JavaScript

var numbers = [5, 458 , 120 , -215 ]; var maxInNumbers = Math.max.apply(Math, numbers), //458 maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458

1
2
3
var  numbers = [5, 458 , 120 , -215 ];
var maxInNumbers = Math.max.apply(Math, numbers),   //458
    maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458

number 自己并未有 max 方法,不过 Math 有,大家就能够依靠 call 只怕 apply 使用其方法。

三、验证是或不是是数组(前提是toString()方法未有被重写过)

JavaScript

functionisArray(obj){ returnObject.prototype.toString.call(obj) === '[object Array]' ; }

1
2
3
functionisArray(obj){
    returnObject.prototype.toString.call(obj) === '[object Array]' ;
}

4、类(伪)数组使用数组方法

JavaScript

var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));

1
var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));

Javascript中留存一种名称叫伪数组的目的组织。相比特别的是 arguments 对象,还有像调用 getElementsByTagName , document.childNodes 之类的,它们再次回到NodeList对象都属于伪数组。不可能应用 Array下的 push , pop 等措施。

唯独大家能透过 Array.prototype.slice.call 转变为实在的数组的涵盖 length 属性的对象,那样 domNodes 就可以运用 Array 下的享有办法了。

深深精通运用apply、call

下面就借用一道面试题,来更浓厚的去驾驭下 apply 和 call 。

概念一个 log 方法,让它能够代办 console.log 方法,常见的消除形式是:

JavaScript

function log(msg) { console.log(msg); } log(1); //1 log(1,2); //1

1
2
3
4
5
function log(msg) {
  console.log(msg);
}
log(1);    //1
log(1,2);    //1

地点方法能够缓和最基本的须求,可是当传入参数的个数是不分明的时候,下边的措施就失效了,这一年就能够思索选用apply 恐怕call,注意这里传出几个参数是不鲜明的,所以利用apply是最佳的,方法如下:

JavaScript

function log(){ console.log.apply(console, arguments); }; log(1); //1 log(1,2); //1 2

1
2
3
4
5
function log(){
  console.log.apply(console, arguments);
};
log(1);    //1
log(1,2);    //1 2

接下去的渴求是给每二个 log 新闻增加1个”(app)”的前辍,例如:

JavaScript

log("hello world"); //(app)hello world

1
log("hello world");    //(app)hello world

该如何是好相比优雅呢?这一年要求想到arguments参数是个伪数组,通过 Array.prototype.slice.call 转化为行业内部数组,再使用数组方法unshift,像那样:

JavaScript

function log(){ var args = Array.prototype.slice.call(arguments); args.unshift('(app)'); console.log.apply(console, args); };

1
2
3
4
5
6
function log(){
  var args = Array.prototype.slice.call(arguments);
  args.unshift('(app)');
 
  console.log.apply(console, args);
};

bind

说完了 apply 和 call ,再来讲说bind。bind() 方法与 apply 和 call 很一般,也是足以改变函数体内 this 的针对性。

MDN的演讲是:bind()方法会创设二个新函数,称为绑定函数,当调用这些绑定函数时,绑定函数会以创办它时传出 bind()方法的首个参数作为 this,传入 bind() 方法的第三个以及现在的参数加上绑定函数运转时自作者的参数遵照顺序作为原函数的参数来调用原函数。

直白来看望实际怎样利用,在广阔的单人体模型式中,常常大家会采取 _this , that , self 等保存 this ,那样大家能够在改造了上下文之后继续引用到它。 像这样:

JavaScript

var foo = { bar : 1, eventBind: function(){ var _this = this; $('.someClass').on('click',function(event) { /* Act on the event */ console.log(_this.bar); //1 }); } }

1
2
3
4
5
6
7
8
9
10
var foo = {
    bar : 1,
    eventBind: function(){
        var _this = this;
        $('.someClass').on('click',function(event) {
            /* Act on the event */
            console.log(_this.bar);     //1
        });
    }
}

由于 Javascript 特有的建制,上下文意况在 eventBind:function(){ } 过渡到 $(‘.someClass’).on(‘click’,function(event) { }) 发生了改观,上述使用变量保存 this 那些艺术都是实惠的,也未尝什么难题。当然使用 bind() 可以更进一步高雅的减轻这几个主题材料:

JavaScript

var foo = { bar : 1, eventBind: function(){ $('.someClass').on('click',function(event) { /* Act on the event */ console.log(this.bar); //1 }.bind(this)); } }

1
2
3
4
5
6
7
8
9
var foo = {
    bar : 1,
    eventBind: function(){
        $('.someClass').on('click',function(event) {
            /* Act on the event */
            console.log(this.bar);      //1
        }.bind(this));
    }
}

在上述代码里,bind() 创设了二个函数,当以此click事件绑定在被调用的时候,它的 this 关键词会被设置成被传到的值(这里指调用bind()时传出的参数)。由此,这里大家传入想要的内外文 this(其实正是 foo ),到 bind() 函数中。然后,当回调函数被施行的时候, this 便指向 foo 对象。再来叁个轻巧的栗子:

JavaScript

var bar = function(){ console.log(this.x); } bar(); // undefined var func = bar.bind(foo); func(); // 3

1
2
3
4
5
6
7
var bar = function(){
    console.log(this.x);
}
 
bar(); // undefined
var func = bar.bind(foo);
func(); // 3

此地大家制造了一个新的函数 func,当使用 bind() 创造一个绑定函数之后,它被实行的时候,它的 this 会被设置成 foo , 而不是像大家调用 bar() 时的大局功用域。

有个风趣的问题,假设接二连三 bind() 一次,亦也许是连接 bind() 三次那么输出的值是何许啊?像这么:

JavaScript

var bar = function(){ console.log(this.x); } var foo = { x:3 } var sed = { x:4 } var func = bar.bind(foo).bind(sed); func(); //? var fiv = { x:5 } var func = bar.bind(foo).bind(sed).bind(fiv); func(); //?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var bar = function(){
    console.log(this.x);
}
var foo = {
    x:3
}
var sed = {
    x:4
}
var func = bar.bind(foo).bind(sed);
func(); //?
 
var fiv = {
    x:5
}
var func = bar.bind(foo).bind(sed).bind(fiv);
func(); //?

答案是,四次都仍将出口 三 ,而非期待中的 四 和 伍。原因是,在Javascript中,数十次 bind() 是低效的。更加深等级次序的来头, bind() 的达成,也等于接纳函数在里边包了3个 call / apply ,第1次 bind() 相当于再包住第3回 bind() ,故第四回之后的 bind 是无力回天生效的。

apply、call、bind比较

那么 apply、call、bind 三者相比较,之间又有怎么着异同呢?几时使用 apply、call,哪天使用 bind 呢。轻易的3个板栗:

JavaScript

var obj = { x: 81, }; var foo = { getX: function() { return this.x; } } console.log(foo.getX.bind(obj)()); //81 console.log(foo.getX.call(obj)); //81 console.log(foo.getX.apply(obj)); //81

1
2
3
4
5
6
7
8
9
10
11
12
13
var obj = {
    x: 81,
};
 
var foo = {
    getX: function() {
        return this.x;
    }
}
 
console.log(foo.getX.bind(obj)());  //81
console.log(foo.getX.call(obj));    //81
console.log(foo.getX.apply(obj));   //81

多个出口的都以八一,可是注意看使用 bind() 方法的,他前面多了对括号。

也便是说,不一致是,当你期望改造上下文境遇之后不要立时施行,而是回调实施的时候,使用 bind() 方法。而 apply/call 则会立马施行函数。

再总括一下:

  • apply 、 call 、bind 三者都以用来改变函数的this对象的对准的;
  • apply 、 call 、bind 3者第二个参数都以this要针对性的目的,也等于想钦赐的上下文;
  • apply 、 call 、bind 三者都得以运用两次三番参数字传送参;
  • bind 是回到对应函数,便于稍后调用;apply 、call 则是立刻调用 。

本文实例出现的装有代码,在自己的github上能够下载。

打赏辅助作者写出越多好作品,多谢!

打赏作者

作者:伯乐在线专栏撰稿人 - chokcoco

如有好小说投稿,请点击 → 这里询问实际情况

如需转发,发送「转发」2字查看表明

诸君观众老爷我们好,接待收看四角裤总动员之程序猿的IT程序大讲堂,今日给我们大饱眼福三个小知识.正是call和apple的差异.

打赏协理小编写出越多好小说,多谢!

任选一种支付办法

图片 1 图片 2

2 赞 16 收藏 4 评论

 

在javascript中, call和apple皆以为着改换有个别函数中运转的上下文而留存的,换句话说就是为了转移函数内部的this的指向.

至于小编:chokcoco

图片 3

经不住小运似水,逃可是此间少年。 个人主页 · 作者的篇章 · 63 ·    

图片 4

那篇小说实在是很难下笔,因为英特网有关小说成千上万。

JavaScript 的一大特色是,函数存在「定义时上下文」和「运转时上下文」以及「上下文是足以改造的」这样的定义。

 

先给我们来一个榛子:

巧合的是今日看到阮老师的1篇文章的一句话:

functionfruits() {}

fruits.prototype = {

color:"red",

say:function() {

console.log("My color is " this.color);

}

}

varapple =newfruits;

apple.say();//My color is red

“对小编来讲,博客首先是壹种知识管理工科具,其次才是传播工具。小编的技艺术小学说,重要用来照顾本身还不懂的知识。小编只写那个自身还未曾完全调节的事物,那一个本身通晓的东西,往往未有引力写。炫丽没有是本人的动机,好奇才是。"

然则只要大家有贰个目的banana= {color : "yellow"} ,我们不想对它再也定义 say 方法,那么大家得以通过 call 或 apply 用 apple 的 say 方法

 

banana = {

color:"yellow"

}

apple.say.call;//My color is yellow

apple.say.apply;//My color is yellow

对此那句话,无法援救越多,也让本身下决心好好写那篇,网络小说虽多,繁多复制粘贴,且晦涩难懂,笔者期望能够由此那篇小说,能够清晰的升级对apply、call、bind的认知,并且列出一部分它们的妙用加深回忆。

之所以,能够看出 call 和 apply 是为着动态改换 this 而产出的,当一个 object 未有有些方法(本栗子中banana未有say方法),可是别的的有(本栗子中apple有say方法),大家得以依赖call或apply用其余对象的办法来操作。

 

对于 apply、call 二者来讲,作用完全一致,只是接受参数的措施不太一样。比如,有八个函数定义如下:

apply、call

varfunc =function(arg1, arg2) {

};

 

就足以经过如下方式来调用:

在 javascript 中,call 和 apply 皆认为着改动有个别函数运维时的上下文(context)而留存的,换句话说,正是为了转移函数体内部 this 的针对。

func.call(this, arg1, arg2);

func.apply(this, [arg1, arg2])

 

内部 this 是你想钦命的上下文,他得以是其它1个 JavaScript 对象(JavaScript 中漫天皆对象),call 必要把参数按顺序传递进入,而 apply 则是把参数放在数组里。

JavaScript 的一大特色是,函数存在「定义时上下文」和「运维时上下文」以及「上下文是足以更换的」那样的定义。

JavaScript 中,有个别函数的参数数量是不固定的,因而要说适用原则的话,当您的参数是显著领会数据时用 call 。

 

而不鲜明的时候用 apply,然后把参数 push 进数组传递进入。当参数数量不分明期,函数内部也足以透过 arguments 这几个数组来遍历全数的参数。

先来3个板栗:

为了加固深化回想,上边罗列部分常用用法:

 

一、数组之间追加

function fruits() {}

 

fruits.prototype = {

color: "red",

say: function() {

console.log("My color is "   this.color);

}

}

 

var apple = new fruits;

apple.say(); //My color is red

vararray1 = [12 ,"foo", {name"Joe"} , -2458];

vararray2 = ["Doe", 555 , 100];

Array.prototype.push.apply(array1, array2);

/* array1 值为 [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */

 

2、获取数组中的最大值和最小值

唯独借使大家有二个对象banana= {color : "yellow"} ,大家不想对它再也定义 say 方法,那么大家能够透过 call 或 apply 用 apple 的 say 方法:

varnumbers = [5, 458 , 120 , -215 ];

varmaxInNumbers = Math.max.apply(Math, numbers),//458

maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215);//458

 

number 本人未有 max 方法,然则 Math 有,我们就足以依靠 call 只怕 apply 使用其格局。

banana = {

color: "yellow"

}

apple.say.call(banana); //My color is yellow

apple.say.apply(banana); //My color is yellow

三、验证是不是是数组(前提是toString()方法未有被重写过)

 

functionisArray{

return Object.prototype.toString.call ==='[object Array]';

}

于是,能够观望 call 和 apply 是为着动态改变 this 而出现的,当三个 object 未有有些方法(本栗子中banana未有say方法),不过其余的有(本栗子中apple有say方法),我们得以依附call或apply用任何对象的法子来操作。

四、类数组使用数组方法

 

vardomNodes = Array.prototype.slice.call(document.getElementsByTagName;

apply、call 的区别

Javascript中设有1种名字为伪数组的对象组织。比较特别的是 arguments

 

目的,还有像调用 getElementsByTagName , document.childNodes 之类的,它们重返NodeList对象都属

对此 apply、call 二者来说,效能完全壹致,只是接受参数的秘籍不太一致。举个例子,有二个函数定义如下:

于伪数组。无法选取 Array下的 push , pop 等措施。

 

而是大家能因而 Array.prototype.slice.call 调换为真正的数组的包涵 length 属性的对象,那样 domNodes 就能够运用 Array 下的保有办法了。

var func = function(arg1, arg2) {

 

};

下边就借出一道面课题,来更长远的去掌握下 apply 和 call 。

 

概念八个 log 方法,让它能够代办 console.log 方法,常见的消除办法是:

就足以因而如下方式来调用:

functionlog {

console.log;

}

log;//1

log;//1

 

地点方法能够消除最大旨的必要,但是当传入参数的个数是不明显的时候,上边的形式就失效了,那年就能够思量采用apply 也许call,注意这里传出多少个参数是不明确的,所以利用apply是最佳的,方法如下:

func.call(this, arg1, arg2);

func.apply(this, [arg1, arg2])

functionlog(){

console.log.apply(console, arguments);

};

log;//1

log;//1 2

 

接下去的渴求是给每3个 log 音信增添2个""的前辍,例如:

其间 this 是你想内定的上下文,他能够是其它八个 JavaScript 对象(JavaScript 中整整皆对象),call 必要把参数按顺序传递进入,而 apply 则是把参数放在数组里。  

log("hello world");//hello world

 

该如何做比较优雅呢?那一年供给想到arguments参数是个伪数组,通过 Array.prototype.slice.call 转化为标准数组,再利用数组方法unshift,像那样:

JavaScript 中,有个别函数的参数数量是不定点的,由此要说适用规则的话,当您的参数是备受关注精晓多少时用 call 。

functionlog(){

varargs = Array.prototype.slice.call(arguments);

args.unshift;

console.log.apply(console, args);

};

 

说完了 apply 和 call ,再来说说bind。bind() 方法与 apply 和 call 很相似,也是足以改动函数体内 this 的针对。

而不明确的时候用 apply,然后把参数 push 进数组传递进入。当参数数量不确定期,函数内部也得以透过 arguments 这一个数组来遍历全体的参数。

MDN的讲明是:bind()方法会创设四个新函数,称为绑定函数,当调用这几个绑定函数时,绑定函数会以创设它时传出 bind()方法的第一个参数

 

用作 this,传入 bind() 方法的第一个以及以后的参数加上绑定函数运维时小编的参数遵照顺序作为原函数的参数来调用原函数。

为了加强深化记念,下边罗列部分常用用法:

直白来探视实际怎么使用,在广大的单人体模型式中,平日我们会利用 _this , that , self 等保存 this ,那样我们得以在转移了上下文之后继续引用到它。 像那样:

本文由68399皇家赌场发布于呼叫中心培训课程,转载请注明出处:深入浅出妙用

关键词: 68399皇家赌场 JavaScript 原型 内裤 区别

最火资讯