关闭

javascript中this,apply和call方法的使用

318人阅读 评论(0) 收藏 举报
分类:

javascript是一种面向对象的编程语言,所以javascript中有this这个特殊的变量。但是这个this和传统的面向对象的语言又不一样,并不是指向当前的对象,而是指向当前的作用域。单纯的文字无法说明问题,下面举一个简单的例子来说明:

<script type="text/javascript">

var color="red";

function showColor(){

  var color = "blue";

  alert(this.color);

}

</script>

如果运行showColor函数,alert会显示哪个值呢?在这里,显示的值是red,有点奇怪吧?这需要从函数运行的作用域说起,所有在全局范围内定义的函数,变量都自动附加在一个全局系统变量window中,所以我们直接运行showColor,和使用window.showColor的效果是一样的。即使前面不加上window,运行环境也会帮我们加上。前面的window就是这个函数运行的作用域,this对象也就是指向这个作用域,所以this.color就等于window.color。

下面这个例子是改变了函数运行的作用域

<script type="text/javascript">

var color="red";

var o=new Object();

o.color="blue";

o.showColor=showColor;

function showColor(){

   alert(this.color);

}

</script>

通过将函数名称赋给引用类型o中的一个变量showColor(这个其实是一个指向函数定义的一个指针)。通过运行o.showColor()改变了函数运行的作用域,现在函数中的this不再指向window变量,而是指向的变量o,所以这儿this.color不再指向window.color,而是指向o.color。所以这儿显示的是blue。

下面这个例子就有点复杂了,因为它涉及到函数中的函数,先上例子

<script type="text/javascript">

var color="red";

var o=new Object();

o.color="blue";

o.showColor=showColor;

function showColor(){

  function message(){

     return this.color;

   }

   alert(message());

}

</script>

运行完o.showColor()的时候,发现显示的又是red值了。这个是因为所有定义的没有明确指定作用域的函数,都是附加在window变量中。也就是说,定义了一个函数,这个函数首先定义两个变量:this(window)和arguments。只有通过明确的指定函数所属对象(作用域)才能改变函数的作用域。所以上面的函数showColor的作用域是o,但是内部函数message的作用域又变成了window,所以这儿的值又变成了red。如何显示o对象中的color的值呢,稍微做一下变动,定义一个showColor作用域的变量,如下

<script type="text/javascript">

var color="red";

var o=new Object();

o.color="blue";

o.showColor=showColor;

function showColor(){

  var that=this;

  function message(){

     return that.color;

   }

   alert(message());

}

</script>

通过that变量访问o.color,现在又显示blue值了。

下面介绍一个apply和call这两个系统函数的用法,每一个函数都可以通过至少三种方式调用,如下面的例子:

<script type="text/javascript">

var color="red";

function showColor(){

   alert(this.color);

}

showColor(); //直接通过函数名调用

showColor.apply(window,null); //通过apply调用,第一个参数是作用域,第二个参数是一个arguments数组

showColor.call(window);  //通过call调用,第一个参数也是作用域,后面如果有参数,是一个参数列表,否则可以不写

</script>

上面例子中的三种调用方式都实现了同样的功能,后面两种方式都比较复杂。javascript作为一种成熟的语言,为什么会提供一些比较复杂的方式实现相同的功能呢?这个就和this变量有点关系了,因为apply和call的第一个参数指定的就是this变量的值。通过下面的例子我们可以有一个大略的了解

<script type="text/javascript">

var o1=new Object();

o1.color="blue";

var o2=new Object();

o2.color="blue";

function showColor(){

   alert(this.color);

}

showColor.apply(o1,null); //通过apply调用,第一个参数是作用域,第二个参数是一个arguments数组

showColor.apply(o2,null); 

</script>

我们定义了两个对象和一个函数,并且使用这一个函数显示两个对象中的color值,但是这两个对象中又没有相应的函数,这时apply或者call函数就作用了(这两个函数的功能是一样的,只不过传递参数的方式不太一样,apply是使用数组的方式传递参数,如func.apply(o,[param1,param2...]),call是func.call(o,param1,param2))。使用apply的第一个参数改变函数运行的作用域,这样就可以显示不同函数中的属性值了。上面的例子只是函数运行的部分,其中这两个函数最最重要的作用是通过改变函数的运行的作用域来实现继承。

 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1732次
    • 积分:75
    • 等级:
    • 排名:千里之外
    • 原创:6篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档