现在这个系统,用到了大量的选择器 和 自动完成,凭借我的三寸不烂之手, 将这些选择器 和 自动完成做到了最简化, 一路顺风顺水.
今天下午补充一个页面的选择器, 要取一个复杂的 json 对像,用来填充数据.
这个 json 对象包含数组, 取出来后,要转变为本地页面(选择器的父页面)的某个"类"的实例.
我用这个方法来将 json 对象转换为某个"类"的对象:
1 _.automap = function (data, type, writeNotExistsProperty, maps, callback, propertyWrap) { 2 /// <summary> 3 /// 将 Json 对象转换为目标类型的对象 4 /// </summary> 5 /// <param name="data">数据</param> 6 /// <param name="type">目标类型</param> 7 /// <param name="writeNotExistsProperty">如果目标类型中不存在对应的属性,是否写入,默认不写入</param> 8 /// <param name="maps">属性映射列表,如{PropertyA:‘PA‘,PropertyB:‘B‘,...}</param> 9 /// <returns type="">目标类型的数据,如果原数据是数组,结果目标类型的数组</returns> 10 if (data == null) 11 return null; 12 13 if (data instanceof Array) { 14 var item, result = []; 15 for (var i = 0; item = data[i]; i++) { 16 result.push(automap(item, type, writeNotExistsProperty, maps, callback, propertyWrap)); 17 } 18 return result; 19 } else if (data instanceof Object) { 20 var result = new type(); 21 for (var k in data) { 22 var targetProperty = k; 23 var value = data[k]; 24 25 if (maps != null) { 26 if (typeof (maps[k]) == "string") { 27 if (typeof (propertyWrap) == "function") 28 targetProperty = propertyWrap(maps[k]) 29 else 30 targetProperty = maps[k]; 31 } else if (typeof (maps[k]) == "function") { 32 value = automap(value, maps[k], msWriteProfilerMark, callback, propertyWrap) 33 } 34 } else if (typeof (propertyWrap) == "function") { 35 value = propertyWrap(value); 36 } 37 38 //不严格等于 39 if (result[targetProperty] !== undefined || writeNotExistsProperty) { 40 result[targetProperty] = value; 41 } 42 } 43 if (callback instanceof Function) { 44 callback(result, data); 45 } 46 return result; 47 } 48 }
结果运后,发现跟本就没有实际的执行, 跟踪了一下,发现问题出现在 data instanceof Array 这个判断上.
传进来的,"我认为" 明明是个数组, 结果却是个 object , 很是郁闷.
可能各位 js 高手不以为然, 这里我写个简单的例子,还原一下场景,找出问题.
有 A / B 两个页面, B模拟我的选择器,也就是子窗口.
A.html
1 <html> 2 <body> 3 <iframe src="b.html" id="b"></iframe> 4 <script> 5 var a = [1,2,3] 6 alert("A.html " + typeof(a) + " " + (a instanceof Array)) 7 8 function alertSub(o){ 9 alert("alertSub without window " + typeof(o) + " " + (o instanceof Array)) ; 10 } 11 12 function alertSubWithWindow(w,o){ 13 alert("alertSub With window " + typeof(o) + " " + (o instanceof w.Array)) ; 14 } 15 16 function alertSubVarType(o){ 17 alert(typeof(o)); 18 } 19 </script> 20 </body> 21 </html>
b.html
1 <html> 2 <body> 3 <script> 4 var a = new Array(1,2,3); 5 var b = "aaa"; 6 var c = new Date(); 7 var d = 100; 8 var e = false; 9 window.parent.alertSub(a); 10 window.parent.alertSubWithWindow(window,a); 11 window.parent.alertSubVarType(b); 12 window.parent.alertSubVarType(c); 13 window.parent.alertSubVarType(d); 14 window.parent.alertSubVarType(e); 15 </script> 16 </body> 17 </html>
b.html 什么也不做,就是声明几个变量, 调用父窗口(A.html) 里的方法.
b.html 里有个 var a = new Array(1,2,3), 通过 window.parent.alertSub(a) 在父页面里用 xxx instanceof Array 来判断它是不是个 Array
猜猜会是什么结果? 声明的是 new Array噢!
弹出的是什么? 是 false !
蛋疼了一会.
想了一下,发现了一个忽略的错误.
Array/ Date 这些内置对象都是在 window 对象下面的.
我们声明 Array 一般不写成 new window.Array, 是因为当前页面的作用域就是 window.
这是个常识,但很容易被忽略.
在做个测试:
window.parent.alertSubWithWindow(window,a);
...
function alertSubWithWindow(w,o){
alert("alertSub With window " + typeof(o) + " " + (o instanceof w.Array)) ;
}
这次是 true 了.
改一下选择器, 原来是这样写的:
var data = $.parseJSON($(this).attr("data-port-info"));
现在改成:
var data = window.parent.$.parseJSON($(this).attr("data-port-info"));
即用父页面的 $.parseJSON 来解析这个 json ,然后传给父页面.
-----------------------------------------------------------------------------------------------------
CNM!GSQ
很久很久以前,有个人事给我说,升职考核的是 综合能力
我来理解一下这个综合能力:
我:
能力70 + 拍马屁10 共 80
他(泛指,请不要对号入座,如果对号也可以):
能力40 + 拍马屁 + 50 共 90
还比我多 10分.