¶àÄêÒÔÀ´£¬ÎÒ¿´µ½ÁËÐí¶àÈ˶ÔÓÚJavaScriptº¯Êýµ÷ÓÃÓкܶàÀ§»ó¡£ÌرðÊÇÐí¶àÈ˻ᱧԹ£¬¡±this¡±ÔÚº¯Êýµ÷ÓÃÖеÄÓïÒåÊÇÁîÈËÒÉ»óµÄ¡£
ÔÚÎÒ¿´À´£¬Í¨¹ýÀí½âºËÐĵĺ¯Êýµ÷ÓõÄÔʼģÐÍ£¬²¢ÇÒÈ¥¿´Ò»ÏÂÔÚ´Ë»ù´¡Ö®ÉÏµÄÆäËû·½Ê½µÄº¯Êýµ÷Ó㨶ÔÔʼµ÷ÓõÄ˼ÏëµÄ³éÈ¡£©¿ÉÒÔÏû³ýÕâЩÀ§»ó¡£Êµ¼ÊÉÏ£¬ECMAScript ±ê×¼Ò²ÊÇÕâô¿¼Âǵġ£ÔÚijЩµØ·½À´¿´£¬ÕâÆªÎÄÕÂÊDZê×¼µÄ¼ò»¯£¬µ«ÊǶþÕߵĻù±¾Ë¼ÏëÊÇÒ»Öµġ£
ºËÐĵÄÔʼº¯Êýµ÷Ó÷½·¨
Ê×ÏÈ£¬ÈÃÎÒÃÇÀ´¿´Ò»ÏºËÐĵĺ¯Êýµ÷ÓÃÔʼģÐÍ£¬Ò»¸öFunctionµÄcall·½·¨[1]¡£call·½·¨Ïà¶Ô±È½ÏÖ±½Ó¡£
- 1¡¢È¡²ÎÊýµÄµÚÒ»¸öµ½×îºóÒ»¸ö×é³ÉÒ»¸ö²ÎÊýÁÐ±í£¨argList£©£»
- 2¡¢µÚÒ»¸ö²ÎÊýÊÇthisValue£»
- 3¡¢°ÑthisÉèÖÃΪthisValueͬʱargList×÷ΪËüµÄ²ÎÊýÁбíÀ´µ÷Óú¯Êý¡£
1
2
3
4
5 |
function hello(thing) {
console.log(this+" says hello "+ thing);
}
hello.call("Yehuda","world")//=> Yehuda says hello world |
ÕýÈçÄãËù¼û£¬ÎÒÃǵ÷ÓÃÁËhelloº¯Êý£¬°ÑthisÉèÖÃΪ¡±Yehuda¡± ²¢´«ÈëÁËÒ»¸ö²ÎÊý¡±world¡±¡£ÕâÊÇJavaScriptº¯Êýµ÷ÓõÄÖ÷ÒªÔʼÐÎʽ¡£Äã¿ÉÒÔ°ÑËùÓÐÆäËûµÄº¯Êýµ÷ÓÃ×÷ΪÕâ¸öÔʼģʽµÄÔËÓÃÀ´¿¼ÂÇ¡££¨Òª¡°ÔËÓá±ÔʼģÐÍÀ´µ÷ÓÃÆäËûº¯Êý¾ÍÒªÓøü±ãÀûµÄÓï·¨²¢ÒÀ¾ÝÒ»¸ö¸ü»ù±¾µÄÖ÷ÒªÔʼģÐÍ£©
×¢£º[1]ÔÚES5±ê×¼ÖУ¬call·½·¨µÄÃèÊö»ùÓÚÆäËûµÄ£¬¸üµÍˮƽµÄ»ùÔª£¬µ«ÊÇËüÊÇÔÚÄǸö»ùÔª»ù´¡Éϵķdz£¼òµ¥µÄ°ü¹ü£¬Òò´ËÎÒÔÚÕâÀォÆä¼ò»¯ÁË¡£ÏëÁ˽â¸ü¶à¿ÉÒԲο¼ÕâÆªÎÄÕºóÃæµÄÐÅÏ¢¡£
¼òµ¥µÄº¯Êýµ÷ÓÃ
ºÜÃ÷ÏÔ£¬×ÜÊÇÓÃcallÀ´µ÷Óú¯ÊýÊÇÁîÈËÄÑÒÔÈÌÊܵġ£JavaScriptÔÊÐíÎÒÃÇÓÃÀ¨ºÅÓï·¨À´Ö±½Óµ÷Óú¯Êý£¨hello(¡°world¡±)£©¡£µ±ÎÒÃÇÕâô×öµÄʱºò£¬µ÷ÓÃÊÇÕâÑùµÄ£º
1
2
3
4
5
6
7
8
9 |
function hello(thing) {
console.log("Hello"+thing);
}
// this:
hello("world")
// desugars to:
hello.call(window,"world"); |
ÔÚECMAScript 5 ÖУ¬ÔÚÑϸñģʽÏÂÕâ¸öÐÐΪÒѾ·¢ÉúÁ˱仯[2]£º
1
2
3
4
5 |
// this:
hello("world")
// desugars to:
hello.call(undefined,"world"); |
¼ò¶ÌµÄÒ»¸ö°æ±¾ËµÃ÷ÊÇ£ºÒ»¸öº¯Êýµ÷ÓñÈÈ磺fn(¡args)Óëfn.call(window [ES5-strict: undefined], ¡args)ÊÇÒ»ÑùµÄ¡£
×¢Ò⣬¶ÔÓÚÐÐÄڵĺ¯ÊýÉùÃ÷(function() {})() Óë(function() {}).call(window [ES5-strict: undefined)Ò²ÊÇÒ»ÑùµÄ¡£
×¢£º[2] ʵ¼ÊÉÏ£¬ÎÒÈöÁ˵ã»Ñ¡£ECMAScript 5 ±ê׼˵undefined£¨¼¸ºõ£©×ÜÊDZ»´«È룬µ±²»ÔÚÑϸñģʽÏÂʱ£¬±»µ÷Óõĺ¯ÊýÓ¦¸Ã¸Ä±äthisµÄֵΪȫ¾Ö¶ÔÏó¡£ÕâÔÊÐíÑϸñģʽµÄµ÷ÓÃÕß±ÜÃâ´òÆÆÒѾ´æÔڵķÇÑϸñģʽ¿â¡£
³ÉÔ±º¯Êý
ÏÂÃæÒ»Öַdz£³£Óõĺ¯Êýµ÷Ó÷½Ê½ÊǺ¯Êý×÷Ϊһ¸ö¶ÔÏóµÄ·½·¨³ÉÔ±À´µ÷Óã¨person.hello()£©¡£ÕâÖÖÇé¿öϺ¯Êýµ÷ÓÃÏñÕâÑù£º
1
2
3
4
5
6
7
8
9
10
11
12 |
var person = {
name: "Brendan Eich",
hello: function(thing) {
console.log(this+"says hello"+ thing);
}
}
// this:
person.hello("world")
// desugars to this:
person.hello.call(person,"world"); |
×¢Ò⣬ÕâºÍhello·½·¨ÒÔÕâÖÖÐÎʽ¸½¼Óµ½¶ÔÏóÖ®ºó»á±äµÃÔõÑùÊÇÎ޹صġ£¼Çס£¬ÎÒÃÇ֮ǰ¶¨ÒåhelloΪһ¸ö¶ÀÁ¢µÄº¯Êý¡£ÈÃÎÒÃÇÀ´¿´¿´¶¯Ì¬µÄ°Ñº¯Êý¸½¼Óµ½¶ÔÏóÉÏ·¢ÉúÁËʲô£º
1
2
3
4
5
6
7
8
9
10 |
function hello(thing) {
console.log(this+"says hello"+thing);
}
person = { name:"Brendan Eich"}
person.hello =hello;
person.hello("world")// still desugars to person.hello.call(person, "world")
hello("world")// "[object DOMWindow]world" |
×¢Ò⣬º¯Êý²¢Ã»ÓС±this¡±µÄÒ»¸ö³Ö¾ÃµÄ¸ÅÄî¡£Ëû×ÜÊÇÔÚ±»µ÷ÓõÄʱºò»ùÓÚµ÷ÓÃÕßµ÷ÓÃËüµÄ·½Ê½±»ÉèÖá£
Ó¦ÓÃFunction.prototype.bind
ÓÉÓÚ¶ÔÒ»¸öÓµÓг־õÄthisµÄÖµµÄº¯ÊýµÄÒýÓÃÓÐʱºòÊǷdz£·½±ãµÄ£¬ÀúÊ·ÉÏÈËÃÇÓÃÁËÒ»¸ö±Õ°ü°ÑÏ·°ÑÒ»¸öº¯Êýת»¯ÎªÁËÓµÓв»±äµÄthisÖµ£º
¾¡¹ÜÎÒÃǵÄboundHello ·½·¨ÈÔÈ»¿ÉÒÔ¸ÄдΪboundHello
1
2
3
4
5
6
7
8
9
10 |
var person = {
name:"Brendan Eich",
hello:function(thing) {
console.log(this.name +"says hello"+thing);
}
}
var boundHello=function(thing){retur person.hello.call(person,thing); }
boundHello("world"); |
.call(window, ¡°world¡±) £¬ÎÒÃÇת»»ÁËÒ»¸ö½Ç¶È£¬Ó¦ÓÃÎÒÃǵĻùÔªcall·½·¨À´¸Ä±äthisΪÎÒÃÇÆÚÍûµÄÖµ¡£
ÎÒÃÇ¿ÉÒÔÓÃ×ÔÖÆÌåϵÀ´Ê¹µÃÕâ¸öÇÏÃÅÓÐÒ»°ãÓÃ;£º
1
2
3
4
5
6
7
8 |
var bind=function(func,thisValue) {
return function(){
return func.apply(thisValue,arguments);
}
}
var boundHello= bind(person.hello,person);
boundHello("world")//"Brendan Eich says hello world" |
ΪÁËÀí½âÉÏÃæµÄ´úÂ룬ÄãÖ»ÐèÒªÁ½¸ö¶îÍâµÄÐÅÏ¢¡£Ê×ÏÈ£¬argumentsÊÇÒ»¸öÀàÊý×é¶ÔÏó£¬ËüÓµÓд«µ½º¯ÊýÀïµÄËùÓвÎÊýµÄÒýÓᣵڶþ£¬apply·½·¨µÄ¹¤×÷»úÖÆºÍ»ùÔªcallÊÇÍêȫһÑùµÄ£¬Î¨Ò»µÄ²»Í¬ÊÇËü²ÉÓõÄÒ»¸öÀàÊý×éµÄ¶ÔÏóÀ´×÷Ϊ²ÎÊý£¬¶ø²»ÊÇÓòÎÊýÁÐ±í¡£
ÎÒÃÇµÄ bind·½·¨¼òµ¥µÄ·µ»ØÒ»¸öк¯Êý¡£µ±Ëü±»µ÷ÓõÄʱºò£¬ÎÒÃǵÄк¯Êý¼òµ¥µÄµ÷Óô«½øÀ´µÄÔʼº¯Êý£¬ÉèÖÃÔʼֵΪthis¡£ËüÒ²±éÀú²ÎÊý¡£
ÒòΪthisÔÚijÖ̶ֳÈÉÏÊÇÒ»¸ö³£¼ûµÄϰÓES5ÒýÈëÁËÒ»¸öеÄbind·½·¨¸øËùÓеÄFunction¶ÔÏóÀ´ÊµÏÖÏÂÃæµÄÐÐΪ£º
1
2 |
var boundHello = person.hello.bind(person);
boundHello("world")//"Brendan Eich says hello world" |
µ±ÄãÐèÒªÒ»¸öδ¼Ó¹¤µÄº¯Êý×÷Ϊ»Øµ÷º¯ÊýµÄʱºòÕâÊǷdz£ÓÐÓõģº
1
2
3
4
5
6
7
8 |
var person = {
name:"Alex Russell",
hello:function(){console.log(this.name +"says hello world"); }
}
$("#some-div").click(person.hello.bind(person));
// when the div is clicked, "Alex Russell says hello world" is printed |
µ±È»£¬Õâ¸öʵÏÖÓÐµã±¿ÖØ£¬¶øÇÒTC39£¨¸ºÔðECMAScriptÏÂÒ»¸ö°æ±¾µÄίԱ»á£©ÕýÔÚʵÏÖÒ»¸ö¸ü¼ÓÓÅÑŵÄÇÒÏòºó¼æÈݵĽâ¾ö·½°¸¡£
jQueryÀïÃæµÄbind
ÒòΪjQueryÀïÃæ´óÁ¿µÄÓ¦ÓÃÄäÃû»Øµ÷º¯Êý£¬ËüÄÚ²¿Ê¹ÓÃcall·½·¨À´ÉèÖÃÄÇЩ»Øµ÷º¯ÊýµÄthisֵΪ¸üÓÐÓõÄÖµ¡£±ÈÈ磬ÔÚËùÓеÄʼþ´¦ÀíÆ÷º¯ÊýÖУ¬jQueryûÓнÓÊÕwindow×÷ΪthisµÄÖµ£¨Èç¹ûÄãûÓÐÌØÊâµÄ¸ÉÔ¤£©£¬¶øÊǶÔÔªËØµ÷ÓÃcall·½·¨£¬²¢½«Ê¼þ´¦ÀíÆ÷º¯Êý×÷ΪµÚÒ»¸ö²ÎÊý¡£
Õ⼫ÆäÓÐÓã¬ÒòΪÔÚÄäÃûº¯ÊýÄÚ²¿µÄthisµÄĬÈÏÖµ²¢²»ÊÇÌØ±ðÓÐÓ㬵«ÊÇËü»á¸øJavaScript³õѧÕßÒ»¸öÕâÑùµÄ¸Ð¾õ£ºthisÒ»°ãÊÇºÜÆæ¹ÖµÄ£¬²¢ÇÒÊÇÄÑÒÔÍÆ²âµÄ¾³£±ä»¯µÄÒ»¸ö¸ÅÄî¡£
Èç¹ûÄãÀí½âÁË´ÓÒ»¸öÓÐÓï·¨Ìǵĺ¯Êýµ÷Óõ½³éÈ¡³öÁË¡°ÌÇ·Ö¡±µÄº¯Êýµ÷ÓÃfunc.call(thisValue, ¡args)µÄ»ù±¾×ª»»¹æÔò£¬ÄãÓ¦¸Ã¾ÍÄܲÙ×ÝÕâ¸ö²¢²»ÊÇÊ®·Ö¡°ÒõÏÕ¡±µÄ JavaScript this ÖµÕâÒ»ÁìÓò¡£

¸½£ºÎÒÓÐËù¡®ÆÛÆ¡¯
ÔÚ¼¸¸öµØ·½£¬¶ÔÓڹ淶µÄ´ë´ÇÎÒÓÐËù¼ò»¯¡£»òÐí×îÖØÒªµÄ¡®ÆÛÆ¡¯ÊÇÎÒ½«func.call³ÆÎªÒ»¸ö»ùÔª£¨¡±primitive¡±£©¡£Êµ¼ÊÉÏ£¬Õâ¸ö¹æ·¶ÓÐÒ»¸ö»ùÔª£¨ÔÚÄÚ²¿±»³ÆÎª[[Call]]£©Îªfunc.callºÍobj.]func()Ëù¹²ÓС£
È»¶ø£¬ÈÃÎÒÃÇÀ´¿´Ò»ÏÂfunc.callµÄ¶¨Ò壺
- 1¡¢Èç¹ûIsCallable(func) ½á¹ûΪfalse£¬ÄÇô¾ÍÅ׳öÒ»¸öÀàÐÍÒì³££»
- 2¡¢Èà argList Ϊһ¸ö¿ÕÁÐ±í£»
- 3¡¢Èç¹ûÕâ¸ö·½·¨±»µ÷ÓõÄʱºò²ÎÊý²»Ö¹Ò»¸ö£¬ÄÇô´Ó×óµ½ÓÒ¿ªÊ¼½«arg1×·¼Óÿһ¸ö²ÎÊý×÷Ϊ argList µÄ×îÐÂÔªËØ£»
- 4¡¢·µ»Øµ÷ÓÃfuncµÄÄÚ²¿·½·¨[[Call]]µÄÖ´Ðнá¹û£¬ÌṩthisArg×÷ΪthisµÄÖµ£¬argList×÷Ϊ²ÎÊýµÄÁÐ±í¡£
ÕýÈçÄãËù¼û£¬Õâ¸ö¶¨Òå±¾ÖÊÉÏÊÇÒ»¸öºÜ¼òµ¥µÄJavaScriptµÄÓïÑ԰󶨵½»ùÔª[[Call]]²Ù×÷·û¡£
Èç¹ûÄ㿴һϺ¯Êýµ÷Óõ͍Ò壬ǰÆß²½ÊÇÉèÖÃthisValueºÍargList£¬×îºóÒ»²½ÊÇ£º¡°·µ»Ø µ÷ÓÃfuncµÄÄÚ²¿·½·¨ [[Call]]µÄ½á¹ûÖµ£¬ÌṩthisArg×÷ΪthisµÄÖµ£¬argList×÷Ϊ²ÎÊýµÄÁÐ±í¡±¡£
Ò»µ©thisValueºÍargListµÄÖµ±»È·¶¨£¬func.callµÄ¶¨ÒåºÍº¯Êýµ÷Óõ͍Òå±¾ÖÊÉÏÊÇÏàͬµÄ×ÖÑÛ¡£
ÎÒÔÚ³ÆcallΪһ¸ö»ùÔªÉÏ×öÁËÒ»µãÆÛÆ£¬µ«ÊÇÔÚ±¾ÖÊÉÏËûÃÇÒâ˼»¹ÊÇÒ»ÑùµÄ£¬ÎÒÔÚÎÄÕ¿ªÍ·Äóö¹æ·¶ÇÒ×öÁËÒýÓá£
»¹ÓкܶసÀý£¨´ó¶àÊýÎÄÕ»áÃ÷ÏԵİüº¬with£©ÎÒûÓÐÔÚÎÄÕÂÖнøÐÐÌÖÂÛ¡£
|