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

原创 2013年12月01日 22:47:34

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的第一个参数改变函数运行的作用域,这样就可以显示不同函数中的属性值了。上面的例子只是函数运行的部分,其中这两个函数最最重要的作用是通过改变函数的运行的作用域来实现继承。

 

JavaScript中call与apply方法

  • 2014年03月11日 20:45
  • 18KB
  • 下载

JavaScript 中apply()、call()和bind()方法的使用

apply()和call()我们可以将call()和apply()看做是某个对象的方法,通过调用此方法来简介调用函数。 call()和apply()两个方法实际上差别不大,只是在方法的第二个参数类别...
  • sf_cyl
  • sf_cyl
  • 2016年07月25日 23:17
  • 263

JavaScript方法call,apply,caller,callee,bind的使用详解及区别

一、call 方法 调用一个对象的一个方法,以另一个对象替换当前对象(其实就是更改对象的内部指针,即改变对象的this指向的内容)。 即  “某个方法”当做“指定的某个对象”的“方法”...
  • xxb2008
  • xxb2008
  • 2012年08月14日 09:13
  • 7547

javascript中call、apply、bind方法的使用

context的概念在知道我们为什么要使用call、apply、bind方法之前,我觉得有必要先了解一下context的相关概念,通常context的作用是取决于函数将如何被调用,当函数作为对象的方法...

Java程序员的JavaScript学习笔记(3——this/call/apply)

这是笔记的第3篇,聊聊JavaScript中的this,还有两种调用函数的特殊方式:call 和 apply。...

JavaScript中this、apply()、call()的用法及解释示例

说到javascript中的this不得不提及javascript中函数调用的四种模式,即 函数调用模式 对象的方法调用模式 构造函数调用模式 上下文调用模式 因为不同的函数调用模式,this的指向时...

理解JavaScript中的this、call和apply

原文地址:点击打开链接 在javascript中,this关键字总让一些初学者迷惑,Function.prototype.call, Function.prototype.apply这两个方法广...

Javascript中的this,call,apply,bind!

今天无意间在这里看到一篇说js中this的文章,看后满是疑问。。。  作者试用this.xXP作windowsroperty取某些属性得到了undefined等一系列非意料中的结果  于是认为导致这种...

JavaScript进阶设计模式系列——基础篇——this-call-apply

this在JavaScript的世界中,this是一个很让人挠头的概念,为什么呢?第一,它总是指向一个对象,使用起来可以简化代码。第二,它是基于函数的执行环境进行动态绑定的,而不是在函数被声明时的环境...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:javascript中this,apply和call方法的使用
举报原因:
原因补充:

(最多只允许输入30个字)