JavaScript 使用方括号([])引用对象的属性和方法 createDelegate
在JavaScript中,每个对象可以看作是多个属性(方法)的集合,引用一个属性(方法)
很简单,即:
对象名.属性(方法)名
除此之外,还可以用方括号的形式来引用:
对象名[“属性(方法)名”]
注意,这里的方法名和属性名是一个字符串,而非原先点号后面的标识符
var arr=new Array(); //为数组添加一个元素 arr[“push”](“abc”); //获得数组的长度 var len=arr[“length”]; //输出数组的长度 alert(len);
等效于
var arr=new Array(); //为数组添加一个元素 arr.push( “abc”); //获得数组的长度 var len=arr.length; //输出数组的长度 alert(len);
这种引用属性(方法)的方式和数组类似,也体现出一个JavaScript对象就是一组属性
(方法)的集合这个性质。
这种用法适合不确定具体要引用哪个属性(方法)的场合
function User(){ this.age=21; this.sex="male"; } //创建user 对象 var user=new User(); //根据下拉列表框显示用户的信息 function show(slt){ if(slt.selectedIndex!=0){ alert(user[slt.value]); //等效于alert(eval(“user.”+slt.value)); } } //--> </script> <!--下拉列表框用于选择用户信息--> <select onchange="show(this)"> <option>请选择需要查看的信息:</option> <option value="age">年龄</option> <option value="sex">性别</option> </select>
带参数的方法的传递
var fun = {}; var show = function (a) { alert(a); } // fun["show"] = show(); undefined fun["show"] = window["show"]; //有效
fun["show"]=show; //有效(不能加刮号) fun.show("aa");
这是对象传对象。
关于调用对象的方法
当一个方法没有调用自身以外的元素时,可以直接赋值
一个方法调用本身以外的元素
属性
var obj = { name: "hongda", fun: function () { console.trace(); Ext.Msg.alert("", this.name); }, show: function () { console.trace(); alert(this.name); } } var obj2 = {}; obj2.show = obj.show; obj.show(); //"hongda" obj2.show(); //undefined
方法:
var obj = { name: "hongda", fun: function () { console.trace(); Ext.Msg.alert("", this.name); }, show: function () { console.trace(); this.fun();} } var obj2 = {}; obj2.show = obj.show; obj.show(); console.log("obj2"); obj2.show();
obj2.show()就是一个错误的方法.
这种引用就像C#中的值传参,下面是类似引用传参的
var obj = { name: "hongda", fun: function () { console.trace(); Ext.Msg.alert("", this.name); }, show: function () { console.trace(); this.fun();} } var obj2 = {}; obj2.show = obj.show.createDelegate(obj); obj.show(); console.log("obj2"); obj2.show();
注意:虽然只弹出了一次,但这不是调用的问题,是ExtJS框架的问题,Ext.Msg.alert的操作有多个时只执行最后一个,事件也是,不晓得是不是一个bug.
createDelegate : function(obj, args, appendArgs){ var method = this; return function() { var callArgs = args || arguments; if(appendArgs === true){ callArgs = Array.prototype.slice.call(arguments, 0); callArgs = callArgs.concat(args); }else if(typeof appendArgs == "number"){ callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first var applyArgs = [appendArgs, 0].concat(args); // create method call params Array.prototype.splice.apply(callArgs, applyArgs); // splice them in } return method.apply(obj || window, callArgs); }; },
通过createDelegate方法就可以执行类似引用传递的方法,最后还是在obj.show中执行。
看看createDelegate.
var obj = { name: "hongda", fun: function () { console.trace(); alert( this.name); }, show: function () { console.trace(); this.fun();} } var obj2 = {}; console.log("apply"); // obj2.show = obj.show.apply(obj, null); //这是直接调用了 obj2.show = function () { obj.show.apply(obj, null); } //show是一个方法,要返回一个方法。 console.log("obj"); obj.show(); console.log("obj2"); obj2.show();
在createDelegate源码中
appendArgs==true,添加参数(arguments数列+args)
var obj = { fun: function (c,d) { console.trace(); alert(c+"|||"+d); }, show: function (a,b) { console.trace(); this.fun(a,b);} } var obj2 = {}; // obj2.show = obj.show.createDelegate(obj, [], true); // obj2.show("cc","ddddd"); //cc|||dddd // obj2.show(); //undefined|||undefined // obj2.show=obj.show.createDelegate(obj,["ee"],true); // obj2.show("cc","ddddd"); //cc|||ddddd // obj2.show(); //ee|||undefined // obj2.show = obj.show.createDelegate(obj, ["aa", "bbb"], true); // obj2.show(); //aa|||bbb // obj2.show("cc","ddd"); //cc|||ddd // obj2.show = obj.show.createDelegate(obj, ["aa", "bbb", "ccc", "d"], true); // obj2.show(); //aa|||bbb // obj2.show("cc","ddd"); //cc|||ddd
Function.prototype.delegate = function (obj, args, appendArgs) { var method = this; return function () { var callArgs = args || arguments; console.log("arguments"); console.dir(arguments); console.log("callArgs"); console.info("callArgs:" + callArgs); if (appendArgs === true) { callArgs = Array.prototype.slice.call(arguments, 0); console.info("callArgs:" + callArgs); callArgs = callArgs.concat(args); console.info("callArgs:" + callArgs); } else if (typeof appendArgs == "number") { callArgs = Array.prototype.slice.call(arguments, 0); // arguments数列 var applyArgs = [appendArgs, 0].concat(args); // splice的参数,appendArgs(插入位置),0为插入,args为插入的数组 Array.prototype.splice.apply(callArgs, applyArgs); // 相当于 数列(arguments).splice(appendArgs,0,args); } return method.apply(obj || window, callArgs); }; } var obj = { fun: function (c,d) { console.trace(); alert(c+"|||"+d); }, show: function (a,b) { console.trace(); this.fun(a,b);} } var obj2 = {}; obj2.show = obj.show.delegate(obj, ["aa"], true); obj2.show(); //aa|||undefined obj2.show("cc"); //cc|||aa
type appendArgs=="number",插入参数(利用splice将args数组插入到arguments的数列中)
var obj = { fun: function (c,d) { console.trace(); alert(c+"|||"+d); }, show: function (a,b) { console.trace(); this.fun(a,b);} } var obj2 = {}; obj2.show = obj.show.delegate(obj, ["aa","b"], 1); obj2.show(); //aa|||b obj2.show("cc"); //cc|||aa