父窗口取子窗口的 js 数组

现在这个系统,用到了大量的选择器 和 自动完成,凭借我的三寸不烂之手, 将这些选择器 和 自动完成做到了最简化, 一路顺风顺水.

今天下午补充一个页面的选择器, 要取一个复杂的 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分.

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。