<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_纪念册de作坊</title><subtitle type="text">专注于计算机软件相关技术</subtitle><id>http://feed.cnblogs.com/blog/u/41873/rss</id><updated>2010-12-04T17:25:29Z</updated><author><name>田嵩</name><uri>http://www.cnblogs.com/hust21941/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hust21941/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/41873/rss"/><entry><id>http://www.cnblogs.com/hust21941/archive/2010/12/05/js-proxy-mock.html</id><title type="text">JavaScript 单元测试中 Proxy（代理）和 Mock（打桩）组件的实现</title><summary type="text">单元测试的粒度通常是函数级，而大部分业务类代码不可能只有一个函数，因此我们在进行单元测试的时候就要对每个函数进行独立的测试，但是对单一函数进行测试的时候不可避免会调用到其他函数和接口，为了简化测试用例的编写和测试环境的搭建，我们通常“假定”调用的其他函数和外部接口都是“正确”的并且可以根据输入返回“预期”的结果，这就需要 Mock（打桩）方式来对这些外部函数和接口进行处理，来模拟我们希望的处理方式，简化其内部实现。而在单元测试过程中，有时需要统计某个外部接口被调用的次数、每次调用的参数、返回值等信息，这时就需要通过 Proxy（代理）的方式将原接口“打包”一下，做个代理。</summary><published>2010-12-04T17:00:00Z</published><updated>2010-12-04T17:00:00Z</updated><author><name>田嵩</name><uri>http://www.cnblogs.com/hust21941/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hust21941/archive/2010/12/05/js-proxy-mock.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hust21941/archive/2010/12/05/js-proxy-mock.html"/><content type="html">&lt;p&gt;2年多没更新博客了，似乎进了某团队之后就没什么时间深入专研技术了，现在终于可以挤出些时间总结一下工作中遇到的技术问题了。&lt;/p&gt;&#xD;
&lt;p&gt;单元测试的概念和作用就不多说了，本文主要说说单元测试的打桩。&lt;/p&gt;&#xD;
&lt;p&gt;单元测试的粒度通常是函数级，而大部分业务类代码不可能只有一个函数，因此我们在进行单元测试的时候就要对每个函数进行独立的测试，但是对单一函数进行测试的时候不可避免会调用到其他函数和接口，为了简化测试用例的编写和测试环境的搭建，我们通常&amp;#8220;假定&amp;#8221;调用的其他函数和外部接口都是&amp;#8220;正确&amp;#8221;的并且可以根据输入返回&amp;#8220;预期&amp;#8221;的结果，这就需要 Mock（打桩）方式来对这些外部函数和接口进行处理，来模拟我们希望的处理方式，简化其内部实现。而在单元测试过程中，有时需要统计某个外部接口被调用的次数、每次调用的参数、返回值等信息，这时就需要通过 Proxy（代理）的方式将原接口&amp;#8220;打包&amp;#8221;一下，做个代理。&lt;/p&gt;&#xD;
&lt;p&gt;JavaScript 的灵活性使得代理和打桩都异常简单：写一个函数，在其中调用被代理函数并记录参数、调用次数等信息，再将这个函数赋给被代理的函数，齐活了；打桩更是简单，直接将桩函数赋给原函数，当然也可以轻松的结合代理函数来处理。一个比较通用的原型如下：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;!--&lt;br/&gt;&lt;br/&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/&gt;http://www.CodeHighlighter.com/&lt;br/&gt;&lt;br/&gt;--&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;bind(fn)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;newFn&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;args&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;arguments;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;index&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;newFn.__ProxyMockData;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;newFn.__ProxyMockData.count&lt;/span&gt;&lt;span style="color: #000000"&gt;++&lt;/span&gt;&lt;span style="color: #000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;info&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;caller&amp;nbsp;:&amp;nbsp;newFn.caller,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;args&amp;nbsp;:&amp;nbsp;args,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;time&amp;nbsp;:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;-&lt;/span&gt;&lt;span style="color: #000000"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;newFn.__ProxyMockData.info.push(info);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;time&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Date()).getTime();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;res&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;newFn.__ProxyMockData.ori.apply(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;args);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;info.time&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Date()).getTime()&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;-&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;time;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;info.res&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;res;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;res;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;newFn.__ProxyMockData&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ori&amp;nbsp;:&amp;nbsp;fn,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;count&amp;nbsp;:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;info&amp;nbsp;:&amp;nbsp;[]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;newFn;&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;使用方法也很简单：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;!--&lt;br/&gt;&lt;br/&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/&gt;http://www.CodeHighlighter.com/&lt;br/&gt;&lt;br/&gt;--&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;test()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alert(&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;test&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;);&lt;br /&gt;}&lt;br /&gt;test();&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;alert:&amp;nbsp;test&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;test&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;bind(test);&lt;br /&gt;test();&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;alert:&amp;nbsp;test&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;打桩&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;test.__ProxyMockData.ori&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alert(&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;mock&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;);&lt;br /&gt;};&lt;br /&gt;test();&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;alert:&amp;nbsp;mock&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;alert(&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;test&amp;nbsp;函数调用次数:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;+&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;test.__ProxyMockData.count);&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;alert:&amp;nbsp;2,&amp;nbsp;bind&amp;nbsp;之前的调用不计算&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;当然，作为完整的组件，我们方然要把打桩、获取调用信息的过程进行一次封装而避免外部直接使用 __ProxyMockData，而且在打桩前也要记录下原函数，避免原函数丢失无法恢复，同时也可以提供 unbind 方法恢复被代理的函数。&lt;/p&gt;&#xD;
&lt;p&gt;这份代码有问题么？似乎没啥问题。能解决所有问题么？似乎也不能，试想这样一段代码：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;!--&lt;br/&gt;&lt;br/&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/&gt;http://www.CodeHighlighter.com/&lt;br/&gt;&lt;br/&gt;--&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;test(msg)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;.msg&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;msg;&lt;br /&gt;}&lt;br /&gt;test.prototype.test&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alert(&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;test:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;+&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;.msg);&lt;br /&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;t1&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;test(&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;t1&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;);&lt;br /&gt;t1.test();&lt;br /&gt;&lt;br /&gt;test&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;bind(test);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;t2&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;test(&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;t2&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;);&lt;br /&gt;t2.test();&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;报错了！&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;打桩&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;test.__ProxyMockData.ori&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;(msg)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;.msg&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;mock:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;+&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;msg;&lt;br /&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;t3&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;test(&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;t3&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;);&lt;br /&gt;t3.test();&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;报错了！&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;两处报错，原因皆为&amp;#8220;　&lt;span style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: medium Simsun; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" &gt;&lt;span style="line-height: 12px; text-indent: -12px; font-family: Consolas, 'Lucida Console', monospace; white-space: pre-wrap; color: rgb(255,0,0); font-size: 12px" &gt;Uncaught TypeError: Object [object Object] has no method 'test'　&lt;/span&gt;&lt;/span&gt;&amp;#8221;，原来，我们创建了代理函数（newFn）时并没有把原函数（fn）的 prototype 原型透传，导致 newFn 的实例并没有 test() 原型。找到了问题的根源就好解决问题了，在创建代理函数中，把原函数中的原型进行透传即可，使用 for in 即可轻松实现，而且 for in 会自动屏蔽 constructor 这个特殊的构造函数（当然以防万一也可以显式做个屏蔽）。另外，在透传的时候也可以再次调用 bind 方法，将原型中的成员函数做个代理再传给代理函数。OK，相信看到这你应该已经晕了，一会直接看代码慢慢理解吧。&lt;/p&gt;&#xD;
&lt;p&gt;当然，对代理函数我们要使用 new 来实例化，而在代理函数的过程中，我们却使用了 newFn.__ProxyMockData.ori.apply 这种相当于直接调用函数的方式，没关系，我们已经把 this 透传到原函数，原函数可以正常的对 this 进行必要的处理，而且构造函数返回 undefined（相当于没有返回）也是没有问题的，因为 JavaScript 引擎会自动判断，如果返回的值不是当前类的实例则直接使用 this 当作返回值。最终的代理生成函数和相关测试函数为：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;!--&lt;br/&gt;&lt;br/&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/&gt;http://www.CodeHighlighter.com/&lt;br/&gt;&lt;br/&gt;--&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;bind(fn)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;newFn&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;args&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;arguments;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;index&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;newFn.__ProxyMockData;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;newFn.__ProxyMockData.count&lt;/span&gt;&lt;span style="color: #000000"&gt;++&lt;/span&gt;&lt;span style="color: #000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;info&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;caller&amp;nbsp;:&amp;nbsp;newFn.caller,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;args&amp;nbsp;:&amp;nbsp;args,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;time&amp;nbsp;:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;-&lt;/span&gt;&lt;span style="color: #000000"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;newFn.__ProxyMockData.info.push(info);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;time&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Date()).getTime();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;res&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;newFn.__ProxyMockData.ori.apply(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;args);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;info.time&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Date()).getTime()&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;-&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;time;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;info.res&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;res;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;res;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;newFn.__ProxyMockData&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ori&amp;nbsp;:&amp;nbsp;fn,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;count&amp;nbsp;:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;info&amp;nbsp;:&amp;nbsp;[]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;for&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;key&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;in&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;fn.prototype)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;newFn.prototype[key]&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;bind(fn.prototype[key]);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;newFn;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;test(msg)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;.msg&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;msg;&lt;br /&gt;}&lt;br /&gt;test.prototype.test&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alert(&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;test:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;+&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;.msg);&lt;br /&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;t1&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;test(&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;t1&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;);&lt;br /&gt;t1.test();&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;test:&amp;nbsp;t1&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;test&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;bind(test);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;t2&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;test(&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;t2&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;);&lt;br /&gt;t2.test();&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;test:&amp;nbsp;t2&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;打桩&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;test.__ProxyMockData.ori&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;(msg)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;.msg&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;mock:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;+&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;msg;&lt;br /&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;t3&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;test(&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;t3&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;);&lt;br /&gt;t3.test();&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;test:&amp;nbsp;mock:&amp;nbsp;t3&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;打桩&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;test.prototype.test.__ProxyMockData.ori&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;(msg)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alert(&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;mock:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;+&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;.msg);&lt;br /&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;t4&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;test(&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;t4&lt;/span&gt;&lt;span style="color: #000000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;);&lt;br /&gt;t4.test();&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;mock:&amp;nbsp;mock:&amp;nbsp;t4&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;OK，不知道头晕的同学有没有缓过来，欢迎大家与我交流。&lt;/p&gt; &lt;img src="http://www.cnblogs.com/hust21941/aggbug/1896690.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hust21941/archive/2010/12/05/js-proxy-mock.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hust21941/archive/2008/09/26/htm-ajax-wcf.html</id><title type="text">不用半个 .aspx——使用 Html+Ajax+Wcf 构建高性能的网站</title><summary type="text">ASP.NET 确实很好很强大，但是对服务器资源的消耗也很多，因此一些大型网站更多的是采用静态页+ASP.NET实现，以减少服务器开支。笔者在此突发奇想了一番，想出一个折中的办法。</summary><published>2008-09-26T08:33:00Z</published><updated>2008-09-26T08:33:00Z</updated><author><name>田嵩</name><uri>http://www.cnblogs.com/hust21941/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hust21941/archive/2008/09/26/htm-ajax-wcf.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hust21941/archive/2008/09/26/htm-ajax-wcf.html"/></entry><entry><id>http://www.cnblogs.com/hust21941/archive/2008/09/19/64-managed-32-unmanaged-dll.html</id><title type="text">在 64 位操作系统下 .NET 托管 (Managed) 代码中调用 32 位的非托管 (Unmanaged) 的本机 (Native) DLL</title><summary type="text">近期在做一个小程序，需要用 C# 调用 WinPcap 驱动实现网络嗅探。首先使用 DllImport 加载 Packet.dll (WinPcap 驱动) 文件，然后调用其中的方法。但是在运行时出现如下错误：无法加载DLL，找不到指定的模块。原来是64位和32位平台之间的调用机制导致的。</summary><published>2008-09-19T13:05:00Z</published><updated>2008-09-19T13:05:00Z</updated><author><name>田嵩</name><uri>http://www.cnblogs.com/hust21941/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hust21941/archive/2008/09/19/64-managed-32-unmanaged-dll.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hust21941/archive/2008/09/19/64-managed-32-unmanaged-dll.html"/></entry><entry><id>http://www.cnblogs.com/hust21941/archive/2008/09/05/freereg-qq-com-js-a-js.html</id><title type="text">QQ 号码申请页面下的一个超强的 javascript 解码版 http://freereg.qq.com/js/a.js</title><summary type="text">因为某些特殊的要求，花了10分钟的时间把这个文件解码了。解码之后还要再去分析各函数功能。</summary><published>2008-09-05T07:06:00Z</published><updated>2008-09-05T07:06:00Z</updated><author><name>田嵩</name><uri>http://www.cnblogs.com/hust21941/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hust21941/archive/2008/09/05/freereg-qq-com-js-a-js.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hust21941/archive/2008/09/05/freereg-qq-com-js-a-js.html"/></entry><entry><id>http://www.cnblogs.com/hust21941/archive/2008/09/03/1283436.html</id><title type="text">阿里旺旺与 Microsoft SQL Server 2008 安装程序支持文件 产生严重的冲突导致启动时即崩溃</title><summary type="text"/><published>2008-09-03T14:50:00Z</published><updated>2008-09-03T14:50:00Z</updated><author><name>田嵩</name><uri>http://www.cnblogs.com/hust21941/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hust21941/archive/2008/09/03/1283436.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hust21941/archive/2008/09/03/1283436.html"/></entry><entry><id>http://www.cnblogs.com/hust21941/archive/2008/09/03/wcf-config-ajax-winform.html</id><title type="text">在 ASP.NET 3.5 中使用同时支持 Ajax Json 和 .NET 客户端的 WCF 服务</title><summary type="text">某些开发要求使用 IIS 承载的 WCF 提供数据和实现操作，客户端使用 Ajax Json 和 WinForm，因此要在统一服务上同时绑定用于 Ajax 的 webHttpBinding 和用于 WinForm 的 wsHttpBinding。</summary><published>2008-09-03T02:16:00Z</published><updated>2008-09-03T02:16:00Z</updated><author><name>田嵩</name><uri>http://www.cnblogs.com/hust21941/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hust21941/archive/2008/09/03/wcf-config-ajax-winform.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hust21941/archive/2008/09/03/wcf-config-ajax-winform.html"/></entry><entry><id>http://www.cnblogs.com/hust21941/archive/2008/08/21/xhtml-writer.html</id><title type="text">对XML+XSLT的转换应用特定的过程以改变生成的HTML代码</title><summary type="text">在使用 XslCompiledTransform 对 XML 应用 XSLT 样式表时，转换的结果是写入 XmlWriter，而在平时应用时，可能会遇到对特定的非 HTML 标签转换为 HTML 标签以及附加 javascript 脚本的情况，而且无法直接通过 XSLT 来实现转换；此外，使用 XmlTextWriter 进行写入时对于 &amp;lt;div&amp;gt;&amp;lt;/div&amp;gt; 这样的标签会被写入为 &amp;lt;div /&amp;gt; 导致浏览器可能不能正常解析，而且因为要考虑 XML 的情况，写入效率较低。因此我们在这里从 XmlWriter 派生一个类，来实现我们需要的功能。</summary><published>2008-08-21T07:00:00Z</published><updated>2008-08-21T07:00:00Z</updated><author><name>田嵩</name><uri>http://www.cnblogs.com/hust21941/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hust21941/archive/2008/08/21/xhtml-writer.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hust21941/archive/2008/08/21/xhtml-writer.html"/></entry><entry><id>http://www.cnblogs.com/hust21941/archive/2008/08/16/1269463.html</id><title type="text">《对基于HTTP协议的密码传输安全的一些思考》相关js代码</title><summary type="text">《对基于HTTP协议的密码传输安全的一些思考》相关 javascript 代码。原文参见 http://www.cnblogs.com/hust21941/archive/2008/08/15/http-password-security.html</summary><published>2008-08-16T10:22:00Z</published><updated>2008-08-16T10:22:00Z</updated><author><name>田嵩</name><uri>http://www.cnblogs.com/hust21941/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hust21941/archive/2008/08/16/1269463.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hust21941/archive/2008/08/16/1269463.html"/></entry><entry><id>http://www.cnblogs.com/hust21941/archive/2008/08/15/http-password-security.html</id><title type="text">对基于HTTP协议的密码传输安全的一些思考(附javascript脚本实现)</title><summary type="text">如今的网络环境日益复杂，在局域网中不可避免被他人通过 ARP 欺骗来监听网络流量，或者网关本身监听流量，抑或 ISP 监听网络流量。而在以往的 HTTP 应用中，常见的做法是将密码和其他信息一同明文发送，这就导致用户的密码受到严重的威胁。近日对这个问题做了些许不成熟的思考，写出来和大家讨论一下。</summary><published>2008-08-15T04:04:00Z</published><updated>2008-08-15T04:04:00Z</updated><author><name>田嵩</name><uri>http://www.cnblogs.com/hust21941/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hust21941/archive/2008/08/15/http-password-security.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hust21941/archive/2008/08/15/http-password-security.html"/></entry><entry><id>http://www.cnblogs.com/hust21941/archive/2008/08/13/static-class-property.html</id><title type="text">静态属性和静态构造函数的相关问题</title><summary type="text">静态构造函数由 .NET CLR 加载类后（即首次使用该类时）自动调用，因此不能带任何修饰符和参数，而且最多执行一次。但是如果在初始化时抛出异常的话，会给出该类型初始化错误的异常，并且以后也都将无法使用该类型。此外还有静态多线程锁的问题。</summary><published>2008-08-13T04:26:00Z</published><updated>2008-08-13T04:26:00Z</updated><author><name>田嵩</name><uri>http://www.cnblogs.com/hust21941/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hust21941/archive/2008/08/13/static-class-property.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hust21941/archive/2008/08/13/static-class-property.html"/></entry></feed>
