惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Privacy & Cybersecurity Law Blog
Vercel News
Vercel News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
N
Netflix TechBlog - Medium
罗磊的独立博客
F
Fortinet All Blogs
T
Threatpost
Y
Y Combinator Blog
博客园_首页
美团技术团队
Security Latest
Security Latest
博客园 - 三生石上(FineUI控件)
T
Tailwind CSS Blog
V
V2EX - 技术
The Cloudflare Blog
L
LINUX DO - 热门话题
博客园 - 司徒正美
Jina AI
Jina AI
P
Proofpoint News Feed
宝玉的分享
宝玉的分享
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
Cybersecurity and Infrastructure Security Agency CISA
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
WordPress大学
WordPress大学
The Hacker News
The Hacker News
P
Privacy International News Feed
T
The Exploit Database - CXSecurity.com
Scott Helme
Scott Helme
有赞技术团队
有赞技术团队
V
V2EX
Stack Overflow Blog
Stack Overflow Blog
M
MIT News - Artificial intelligence
Latest news
Latest news
NISL@THU
NISL@THU
Google DeepMind News
Google DeepMind News
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cisco Blogs
雷峰网
雷峰网
Application and Cybersecurity Blog
Application and Cybersecurity Blog
B
Blog RSS Feed
W
WeLiveSecurity
D
DataBreaches.Net
G
Google Developers Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
G
GRAHAM CLULEY
Spread Privacy
Spread Privacy
Know Your Adversary
Know Your Adversary
TaoSecurity Blog
TaoSecurity Blog
S
Securelist
Help Net Security
Help Net Security

博客园 - moge

新建的网站 八方达物流网 How to Implement an Automatic Sliding Window in a Partitioned Table on SQL Server 2005 SQL Server 2005 Partitioned Tables and Indexes 如何估算数据库的大小 MSDN链接 Enabling Change Data Capture SQL Server 操作集锦 转一篇很经典的房价文章 在SharePoint中激活Page Library功能 Database Coding Standard and Guideline 计算机电子书免费下载列表 3 计算机电子书免费下载列表 2 计算机免费电子书下载 1 国外可以赚钱的免费硬盘 推荐一个下载电子书的网站 不需要注册 ASP.NET AJAX客户端生命周期分析(实践篇)(2) 继承CollectionBase的类的xml序列化 101个设计模式 Design Patterns 用C#操作Person or Group列在SharePoint中
Javascript中的apply和call函数
moge · 2009-03-01 · via 博客园 - moge

Posted on 2009-03-01 19:45  moge  阅读(759)  评论()    收藏  举报

通过一个例子说明apply()的用法:

//针对各种浏览器建立一个http request的对象

function getHttpRequest(){
   http_request = null;
   if (window.XMLHttpRequest) {

      http_request = new XMLHttpRequest();
   } else if (window.ActiveXObject) {
       http_request = new ActiveXObject("Microsoft.XMLHTTP");
   }
   return http_request;
}

var ajax_request;

functiong getPerson(){

ajax_request = getHttpRequest();    //建立一个http request

ajax_request.onstatechange = handleResponse; //指定回调函数


ajax_request.send();

}


function handleResponse(){

if(ajax_request.readyState != 4) return;

if(ajax_request.status == 200){

    var xml = ajax_request.responseXML;

    /* 对获得的xml的处理 */

}

}


调用的时候可以直接在页面里调用

getPerson();


这个函数会建立一个httpRequest对象,然后发送请求,在请求返回的时候会自动调用handleResponse函数来完成操作。

在简单的环境上,上述代码会工作得很好,但是如果在一个页面中要执行多次这种操作就比较麻烦了,需要写多个函数,看一下上面的定义:

var ajax_request; 表示这是个全局变量,多次请求的时候每个请求都要用到这个对象,ajax又是异步的,无法事先确定哪个请求先返回。


如果把ajax_request作为函数内的局部变量呢?那样如果在handleResponse里能看到ajax_request对象就可以解决这个问题了。

可以考虑把ajax_request作为一个参数传递给handleResponse,现在的问题是,对handleResponse的调用是自动的,怎么能在参数列表中添加这个参数呢?我们想到了this变量,在javascript中,所有的东西都是对象,this表示当前对象,在函数中this就表示当前的函数。

javascript提供了一种可以改变this的方法——apply()。

javascript对apply的解释是:使用指定对象替换当前对象并调用函数。比如:


function test_apply(){

alert(this);

}

test_apply.apply(document, []);


就表示调用函数test_apply,并用document对象来替换test_apply中的this。


回到刚刚的问题,为了修改当前对象,需要在指定handleResponse的时候就修改this对象。ajax_request.onstatechange是一个函数的句柄,只要我把一个函数的句柄赋值给它就可以了,同时函数也是一种对象,Function对象,因此我们为函数对象添加一个方法:

Function.prototype.setThis(){

var curr_function = this;

var to_this_object = arguments[0];

return function(){

    currFunc.apply(to_this_object, []);

};

}


下面,修改getPerson为:


functiong getPerson(){

var tmp_request = getHttpRequest();    //建立一个http request

tmp_request.onstatechange = handleResponse.setThis(tmp_request); //指定回调函数


tmp_request.send();

}


修改handleResponse为:


function handleResponse(){

if(this.readyState != 4) return;

if(this.status == 200){

    var xml = this.responseXML;

    /* 对获得的xml的处理 */

}

}

即可。

具体的变化就在于tmp_request.onstatechange = handleResponse.setThis(tmp_request);

因为handleResponse是一个函数,因此它具有Function新添加的方法setThis,

下面来看setThis方法:


var curr_function = this; //获得当前的函数本身

var to_this_object = arguments[0]; //获得要指定的新的this对象

return function(){

    currFunc.apply(to_this_object, []);

};


这里的返回值是一个函数,即当tmp_request的onstatechange事件的时候会触发这个函数,该函数中只有一句

currFunc.apply(to_this_object, []);即用to_this_object替换当前对象并调用currFunc,在这里currFunc即代表了handleResponse,因此调用handleResponse,因为已经修改了其this对象,因此在handleResponse中用this即代表了tmp_request对象。


用这种方法可以减化代码,并使代码更具可重用性。
源文地址:http://www.cublog.cn/opera/showart.php?blogid=21787&id=140549

附注:

应用某一对象的一个方法,用另一个对象替换当前对象。

apply([thisObj[,argArray]])参数thisObj可选项。将被用作当前对象的对象。

argArray

可选项。将被传递给该函数的参数数组。

说明

如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。

javascript apply()方法二

官方解释:应用某一对象的一个方法,用另一个对象替换当前对象。

apply与call的区别是第二个参数不同。apply是 数组或者arguments 对象。而call是逗号隔开的任何类型。

<html>
<body>
<div>test</div>
<input id="input" type=button value='click' onclick="c()" class="aa"/>
<script>


function test_apply()

    alert(this.value + " " + arguments[0] + " " + arguments[1]);
}
test_apply.call(document.getElementById("input"),'aa',1);
test_apply.apply(document.getElementById("input"),['aa','1']);

</script>
</body>
</html>