Javascript点滴:this, Function.apply 及Function.call
2009-11-11 13:27
417 查看
考虑以下这段代码:
1
<
input type
=
"
button
"
id
=
"
btnSubmit
"
value
=
"
Click me!
"
/>
2
3
<
script language
=
"
javascript
"
type
=
"
text/javascript
"
>
4
function
ButtonManager(buttonId, message)
5
{
6
this
._message
=
message;
7
document.getElementById(buttonId).onclick
=
this
.ShowMessage;
8
}
9
10
ButtonManager.prototype.ShowMessage
=
function
()
11
{
12
alert(
this
._message);
13
}
14
15
var
btnManager
=
new
ButtonManager(
"
btnSubmit
"
,
"
Hello!
"
);
16
</
script
>
按预想的意图,当点击按钮时,应当会弹出"Hello!",但
上面的代码运行,却弹出"undefined"。问题出在哪里呢?在12行设个断点,对它进行调试,发现this竟然是指向btnSubmit,如果是这
样的话,那就难怪会弹出"undefined",因为btnSubmit本身并没有定义_message,而我们所期望的this应当是指向
btnManager,我们真正期望调用的方法其实是btnManager.ShowMessage()。
事实上,这是与Javascript的语法和运行机制有关的,当ShowMessage真正调用前,this的指向是不明确,而只有在运行里,this的指向会由运行时来决定。
那么有没有什么方法来正确实现上述意图呢?答案是肯定的,首先要可以看下面的代码:
1
var
x
=
10
;
2
var
o
=
{x:
15
}
;
3
function
foo()
4
{
5
alert(this.x);
6
}
7
foo();
8
foo.call(o);
运行之后,我们会发现结果会分别是10和15。这似乎有点疑惑了,当然关键点肯定就是那个Call了。
Javascript
中的function本身也是一个object,它本身就会有tostring(),call(),apply()几个附加方法。这个
function.call的意义就在于,当调用时它时,运行时会把它的第一个参数替换掉function的this指向。
当调用foo()时,this是指向window的,而事实上,所有的全局变量就是window的属性。foo.call(o)时,this是指向o的。
理解了function.call的作用,当解决上面的问题就不难了。
1
<
input type
=
"
button
"
id
=
"
btnSubmit
"
value
=
"
Click me!
"
/>
2
3
<
script language
=
"
javascript
"
type
=
"
text/javascript
"
>
4
function
ButtonManager(buttonId, message)
5
{
6
this
._message
=
message;
7
document.getElementById(buttonId).onclick
=
createDelegate(
this
,
this
.ShowMessage);
8
}
9
10
ButtonManager.prototype.ShowMessage
=
function
()
11
{
12
alert(
this
._message);
13
}
14
15
function
createDelegate(object, method)
16
{
17
var
delegate
=
function
()
18
{
19
method.call(object);
20
}
21
return
delegate;
22
}
23
24
var
btn
=
new
ButtonManager(
"
btnSubmit
"
,
"
Hello!
"
);
25
26
</
script
>
我们加入一个createDelegate的funciton,它的作用类似为onclick事件创建一个事件委托对象。现在,代码可以正常工作了。
另外,function.apply()和function.call()基本功能是一样的,但apply却可以授受两个参数,而且第二个参数必须是一个数组。
1
var
o
=
{x:
10
}
;
2
function
f(message)
3
{
4
alert(message
+
(
this
.x
*
this
.x));
5
}
6
7
function
g(object, func)
8
{
9
var
args
=
[];
10
for
(
var
i
=
2
;i
<
arguments.length;i
++
)
11
{
12
args.push(arguments[i]);
13
}
14
func.apply(object,args);
15
}
16
17
g(o,f,
"
result :
"
);
基于apply的这个特点,apply比call使用更加广泛,在javascript中的继承中,apply的使用也是必不可少的
1
<
input type
=
"
button
"
id
=
"
btnSubmit
"
value
=
"
Click me!
"
/>
2
3
<
script language
=
"
javascript
"
type
=
"
text/javascript
"
>
4
function
ButtonManager(buttonId, message)
5
{
6
this
._message
=
message;
7
document.getElementById(buttonId).onclick
=
this
.ShowMessage;
8
}
9
10
ButtonManager.prototype.ShowMessage
=
function
()
11
{
12
alert(
this
._message);
13
}
14
15
var
btnManager
=
new
ButtonManager(
"
btnSubmit
"
,
"
Hello!
"
);
16
</
script
>
按预想的意图,当点击按钮时,应当会弹出"Hello!",但
上面的代码运行,却弹出"undefined"。问题出在哪里呢?在12行设个断点,对它进行调试,发现this竟然是指向btnSubmit,如果是这
样的话,那就难怪会弹出"undefined",因为btnSubmit本身并没有定义_message,而我们所期望的this应当是指向
btnManager,我们真正期望调用的方法其实是btnManager.ShowMessage()。
事实上,这是与Javascript的语法和运行机制有关的,当ShowMessage真正调用前,this的指向是不明确,而只有在运行里,this的指向会由运行时来决定。
那么有没有什么方法来正确实现上述意图呢?答案是肯定的,首先要可以看下面的代码:
1
var
x
=
10
;
2
var
o
=
{x:
15
}
;
3
function
foo()
4
{
5
alert(this.x);
6
}
7
foo();
8
foo.call(o);
运行之后,我们会发现结果会分别是10和15。这似乎有点疑惑了,当然关键点肯定就是那个Call了。
Javascript
中的function本身也是一个object,它本身就会有tostring(),call(),apply()几个附加方法。这个
function.call的意义就在于,当调用时它时,运行时会把它的第一个参数替换掉function的this指向。
当调用foo()时,this是指向window的,而事实上,所有的全局变量就是window的属性。foo.call(o)时,this是指向o的。
理解了function.call的作用,当解决上面的问题就不难了。
1
<
input type
=
"
button
"
id
=
"
btnSubmit
"
value
=
"
Click me!
"
/>
2
3
<
script language
=
"
javascript
"
type
=
"
text/javascript
"
>
4
function
ButtonManager(buttonId, message)
5
{
6
this
._message
=
message;
7
document.getElementById(buttonId).onclick
=
createDelegate(
this
,
this
.ShowMessage);
8
}
9
10
ButtonManager.prototype.ShowMessage
=
function
()
11
{
12
alert(
this
._message);
13
}
14
15
function
createDelegate(object, method)
16
{
17
var
delegate
=
function
()
18
{
19
method.call(object);
20
}
21
return
delegate;
22
}
23
24
var
btn
=
new
ButtonManager(
"
btnSubmit
"
,
"
Hello!
"
);
25
26
</
script
>
我们加入一个createDelegate的funciton,它的作用类似为onclick事件创建一个事件委托对象。现在,代码可以正常工作了。
另外,function.apply()和function.call()基本功能是一样的,但apply却可以授受两个参数,而且第二个参数必须是一个数组。
1
var
o
=
{x:
10
}
;
2
function
f(message)
3
{
4
alert(message
+
(
this
.x
*
this
.x));
5
}
6
7
function
g(object, func)
8
{
9
var
args
=
[];
10
for
(
var
i
=
2
;i
<
arguments.length;i
++
)
11
{
12
args.push(arguments[i]);
13
}
14
func.apply(object,args);
15
}
16
17
g(o,f,
"
result :
"
);
基于apply的这个特点,apply比call使用更加广泛,在javascript中的继承中,apply的使用也是必不可少的
相关文章推荐
- JavaScript的this, 以及function.call, function.apply
- js的 function, javascript内置对象apply,call,this概念及之间的关系详解
- Java程序员的JavaScript学习笔记(3——this/call/apply)
- javascript之this、new、apply和call详解
- 轻松拿下JavaScript(四)——对象字面量,this,call()和apply()方法,JS的异常处理
- 【学习笔记javascript设计模式与开发实践(this、call和apply)----2】
- Function.apply and Function.call in JavaScript
- 谈谈javascript的Function中那些隐藏的属性/方法:caller/callee/apply/call/bind
- JavaScript call apply使用——JavaScript对象的方法绑定到DOM事件后this指向问题
- JavaScript的this,call(),apply(),bind()
- JavaScript call apply使用 JavaScript对象的方法绑定到DOM事件后this指向问题
- javascript技术难点之this、new、apply和call详解
- [原]Java程序员的JavaScript学习笔记(3——this/call/apply)
- javascript中this、apply、call、bind的用法和区别
- javascript技术难点(三)之this、new、apply和call详解
- javascript Call apply this 迟绑定
- javascript 之Function对象的apply(),call(),bind(),方法和arguments,caller,length属性
- JavaScript之this,new,delete,call,apply
- [Javascript] Specify this using .call() or .apply()