您所在的位置: 首页>>读书频道>>设计开发>>其它开发>>

3.4 完美之绑定(bind)将通用于Object、Function和其他 对象,同时支持给Object增加[ ]运算符号

http://book.51cto.com  2008-04-15 16:26  夏天  电子工业出版社博文视点  我要评论(0)
  • 摘要:《JavaScript高级应用与实践 》第3章主要讲了Object扩展和性能及Web应用之神兵利器,本节将为大家展示的是完美之绑定(bind)将通用于Object、Function和其他 对象,同时支持给Object增加[ ]运算符号,以及它的示意图。
  • 标签:JavaScript  bind  Object  Function  JavaScript高级应用与实践
3.4  完美之绑定(bind)将通用于Object、Function和其他   对象,同时支持给Object增加[ ]运算符号
3.3节的实验已经告诉我们,Function那样的bind技术不够完美,通用性和柔性都不够好,笔者在这一节的目的就是要带领你打造一个更完美的bind,使之既能应用于Object,也能应用于Function对象,请看下面的注解和代码:
    <html>
<head><meta http-equiv=content-type content="text/html; charset=utf-8">
<title>完美之绑定(bind)将通用于Object和Function,同时支持给Object增加[ ]运算符号</title>
<style>
html,body,td,p,div,span,th
{
font-size:9pt;
}
</style>
</head>
<body>
<script type="text/javascript" language="JavaScript"
src="/jcore/resource /javascript/Jcore.js"></script>
<script type="text/javascript" language="JavaScript">
<!--
// 功能描述:封装用于大幅度提升常规for循环语句的性能,
// 如果指定第4个参数为有效的非false参数,则表示倒过来循环
// 不过请注意,这里只是权宜封装,它依然不是最佳选择,欲知详情,参见第6章6.5节
// 返回信息:在function对象的时候返回绑定后的function对象,否则返回绑定后的对象
// 使用指南:例子代码比较多,这里就不给出使用举例了,请见下面的例子
// 应用范围:各种Web客户端和服务端开发
function FastFor(nStart,nForLen, oFunc)
{
try
{
    FastFor.name = "FastFor";
var i = nStart || 0, myth = 8, nLen = nForLen - i, n = nLen % myth, nOld = n, arg = _A(arguments);
// 移出前面3个参数
arg.splice(0,3);
new function(){
// 倒过来循环
if(arg[3])
{
   i = nForLen;
   do{oFunc.apply(this, [].concat([i], arg)),i--}while(0 < --n);
n = (nLen - nOld) / myth;
while(0 < n--)
{
oFunc.apply(this, [].concat([i], arg)),i--;
oFunc.apply(this, [].concat([i], arg)),i--;
oFunc.apply(this, [].concat([i], arg)),i--;
oFunc.apply(this, [].concat([i], arg)),i--;
oFunc.apply(this, [].concat([i], arg)),i--;
oFunc.apply(this, [].concat([i], arg)),i--;
oFunc.apply(this, [].concat([i], arg)),i--;
oFunc.apply(this, [].concat([i], arg)),i--;
}
}
else // 支持倒着循环
{
do{oFunc.apply(this, [].concat([i], arg)),i++}while(0 < --n);
n = (nLen - nOld) / myth;
while(0 < n--)
{
oFunc.apply(this, [].concat([i], arg)),i++;
oFunc.apply(this, [].concat([i], arg)),i++;
oFunc.apply(this, [].concat([i], arg)),i++;
oFunc.apply(this, [].concat([i], arg)),i++;
oFunc.apply(this, [].concat([i], arg)),i++;
oFunc.apply(this, [].concat([i], arg)),i++;
oFunc.apply(this, [].concat([i], arg)),i++;
oFunc.apply(this, [].concat([i], arg)),i++;
}
}}
}catch(e){fnCatch(e)}
}

// 功能描述:功能强大的通用对象的绑定实现,支持function
// 这里出现后就提到"Jcore.js"里,以后章节将不再出现,而
// Jcore.js里原有的function的bind将删除,请读者注意
// 返回信息:在function对象的时候返回绑定后的function对象,否则返回绑定后的对象
// 使用指南:例子代码比较多,这里就不给出使用举例了,请见下面的例子
// 应用范围:各种Web客户端和服务端开发
Object.prototype.bind = function()
{
var a = _A(arguments), _this = this;
switch(_this.constructor)
{
// JavaScript的case支持各种类型,这比其他编程语言强多了
// 针对Function的处理
// 不过要特别注意的是,Function的bind是要返回一个bind以后的函数的应用的
case Function:
// 容错处理,防止bind的时候需要绑定NaN,undefined,null,Infinity等
!!a[0] || (a[0] = window);
var b = _A(arguments);
b.shift();
return function()
{
// b.concat(_A(arguments))是为了支持绑定返回的函数应用能再传入参数
// 如果要调整让传入的参数在最前面,那么_A(arguments).concat(b)
// 换过来就可以了
return _this.apply(a[0], b.concat(_A(arguments)))
};
break;
case Object:
a.each(function()
{
switch(this.constructor)
{
case Object:
// 注意这里的this不等于_this
// 它是a迭代器,迭代进来的a的每一个元素
for(var k in this)
// bind就没有必要再覆盖了
// 读者请注意,这里常量放在逻辑比较运算符号的前面可以防止:
// == 的时候少写了一个"="而很久都无法发现
// != 的时候少写了"!"却不轻易发现
if("bind" != k)
_this[k] = this[k];
// 读者请注意:for in的方式无法枚举出:valueOf、toString、toLocaleString,这里做一个补偿
_this['toString']       = this['toString'];
_this['valueOf']        = this['valueOf'];
_this['toLocaleString'] = this['toLocaleString'];
break;
case Array:     
var _this1 = this;
_this.length || (_this.length = 0);
var n1 = _this1.length % 8, oN = n1;
do
{
   [].push.apply(_this, [_this1[i]]);
}while(0 < n1--);
n1 = (_this1.length - oN) / 8;
do
{
   [].push.apply(_this, [_this1[i]]);[].push.apply (_this, [_this1[i]]);
   [].push.apply(_this, [_this1[i]]);[].push.apply (_this, [_this1[i]]);
   [].push.apply(_this, [_this1[i]]);[].push.apply (_this, [_this1[i]]);
   [].push.apply(_this, [_this1[i]]);[].push.apply (_this, [_this1[i]]);
}while(0 < n1--);
// 或者:注意下面的注释方式,只需要在前面加一个"/"就可以激活代码了
/*/////////////////
_this1.each(function()
{
// 注意这里的this不等于_this1
// 它是_this1迭代器,迭代进来的_this1的每一个元素
[].push.apply(_this, [this]);
});                  
/////////////////*/
break;
default:
_this.length || (_this.length = 0);
// 注意这里的this不等于_this
// 它是a迭代器,迭代进来的a的每一个元素
[].push.apply(_this, [this]);
}

});
return this;
break;
default:return _this;
}
};
// 测试函数的绑定
function fnTestFunctionBind()
{
var a = _A().concat(this);
alert(a.join(" | "))
}
// 这里支持两种形式,下面两行代码执行结果一样
// 都弹出:
// 万物皆为我所用,但非我所属。| 你希望掌握永恒,那你必须控制现在。 | other | 945
//  fnTestFunctionBind.bind(945, ["万物皆为我所用,但非我所属。", "你希望掌握永恒,那你必须控制现在。", "other"])
var oMyFct = fnTestFunctionBind.bind(945, "万物皆为我所用,但非我所属。", "你希望掌握永恒,那你必须控制现在。", "other");
// 效果参见图3-4
// 再次绑定
var oMyFct1 = oMyFct.bind(8888, "看轻别人很容易,要摆平自己却很困难。");
oMyFct("我新传递的参数", 20070804);
// 结果参见图3-5
oMyFct1("第二个bind后调用", "其他参数");
// 别忘了养成良好的习惯,请注意, 这里的顺序也很讲究的
delete oMyFct1;
delete oMyFct;
// 这里用于测试Object的bind
var oTestObject = {
name:"从前的日子",
display:function()
{
alert(this.name);
}
};
// 我们先测试最简单的支持
oTestObject.bind("one", "two", "three");
// 结果参见图3-6
alert([oTestObject[0], oTestObject[1], oTestObject[2]].join("\n\n"));
// 测试混合绑定
oTestObject.bind(["four", "five", "six"], "单个String", 777);
// 结果参见图3-7
alert(_A(oTestObject).join("\n\n"));
// 这里我们测试绑定一个Object和一个Array进去
oTestObject.bind({
age: 150,
fnDisplayAge:function()
{
return [this.name, this.age];
},
toString:function()
{
return "{name:'" + this.name + "',age:" + this.age + "}";
}}, ["第一个下标值", "人家怕你,并不是一种福,人家欺你,并不是一种辱。"]);

// 相当“perfect”地弹出了意愿中的结果,结果参见图3-8
alert(_A([_A(oTestObject).join("\n"), oTestObject.fnDisplayAge(), oTestObject.toString()]).join("\n"));
-->
</script>
</body>
</html>
 
图3-4  function bind效果
 
图3-5  function多次bind后隐含了参数的效果
 
图3-6  bind Object的效果
 
图3-7  混合bind
 
图3-8  复杂bind
【责任编辑:夏书 TEL:(010)68476606】

回书目   上一节   下一节
JavaScript完全自学宝典
C# 3.0完全自学宝典
Visual Basic完全自学宝典
Visual C++ 6.0完全自学宝典
Ajax实战:实例详解
 
 验证码: (点击刷新验证码)   匿名发表
  • 野蛮生长

  • 作者:冯仑著
  • “地产界的思想家”冯仑纵横生意江湖20年来,第一次系统梳理出书。  三十年来中国民营企业从前公司时代发展到公司时代,21..
Copyright©2005-2008 51CTO.COM 版权所有