您的位置:首页 > 移动开发

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的使用也是必不可少的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: