将过去零零散散的问题收集记录于此
复制引用类型数据 经常会遇到需要复制一个array或者object的需求。 如果是简单粗暴的 a = b 这样复制那就可能出问题了,你会发现当b中数据发生变化时, a的数据竟然也改变了,这也许并不是你想见到的结果,因为 a = b 这样对引用类型赋值时,a实际上等于b对象的一个内存地址,也就是说,访问a时实际上访问的是b。 正确复制引用类型的方法如下:
复制array
1
2
3
4
5
6
7
var arr = [];
for (var i = 0 ; i < aUser.length; i++) {
arr.push(aUser[i]);
}
var arr = aUser.concat()
复制object 当object中存的数据为基本数据类型时,可以使用浅拷贝。反之,如果object中有很多层数据时,若使用浅拷贝会发现其子层还是会遇到之前发生的问题
1
2
3
4
5
6
7
var obj = [];
for (var key in oUserData) {
obj[key] = oUserData[key];
}
在iframe子窗口调用父级窗口方法 iframe子窗口调用父级窗口方法分为两种情况,跨越及同域调用
iframe子窗口调用父级窗口 假设父级窗口index.html中有一个closeModal
方法,和一个iframe,我们想在iframe中调用这个方法。
1
2
3
4
5
6
7
<iframe id ="ifr" src ="" > </iframe >
<script type ="text/javascript" >
function closeModal ( ) {
}
</script >
当iframe打开的页面与父窗口在同一个域名下时,我们通过window.parent拿到父窗口的window句柄,从而调用到父窗口window句柄下的方法1
2
3
4
<script type ="text/javascript" >
window .parent.closeModal();
</script >
由于js对跨域权限做了限制,当iframe打开的是另一个域名下的地址时,我们可以通过下面这种方法“巧妙”的调用到父窗口下的方法——在iframe中再嵌入一层子iframe用于打开一个与父级同域名的页面,由于这个子iframe与父级同域,因此可以通过他调用我们需要的方法1
2
<iframe id ="child" src ="" > </iframe >
1
2
3
4
<script type ="text/javascript" >
window .parent.parent.closeModal();
</script >
上述方法非常的“投机”,那么下面这种方法则可以说是名门正派了。
##HTML5中的postMessage HTML5提供了新的通信api——postMessage
,可以允许父容器与子容器间进行通信 那么实现的过程就如下:
1
2
3
4
5
6
7
8
9
10
11
<iframe id ="ifr" src ="" > </iframe >
<script type ="text/javascript" >
function closeModal ( ) {
}
window .addEventListener('message' , function (e ) {
'closeModal' == e.data && closeModal();
},false );
</script >
iframe中通过postMessage向父窗口发消息1
2
3
4
5
6
7
8
9
<script type ="text/javascript" >
parent.postMessage('closeModal' , '*' );
postMessage(data, origin);
参数:data 消息内容
origin 发送消息窗口的源(协议+主机+端口号)
*/
</script >
prototype.function与this.function的区别 prototype.function与this.function都可以定义对象的方法,那二者有何区别呢?
初步分析 先用一段代码来说明二者的区别:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var actor = function ( ) {
var param = 1 ;
this .act = function ( ) {
return param;
}
};
actor.prototype.play = function ( ) {
return typeof param;
};
var man1 = new actor();
var man2 = new actor();
console .log(man1.act === man2.act);
console .log(man1.play === man2.play);
console .log(man1.act());
console .log(man1.play());
简单工厂模式 简单工厂模式(Simple Factory)又叫静态工厂方法,由一个工厂对象决定创建某种产品对象类的实例。
以我的理解,这种设计模式的目的是:统一几个对象的创建入口,这样就可以抽取这几个对象创建时的共性(共用代码),同时可以由该工厂方法决定具体创建那个对象。
比如屏幕中有modal和pop两种弹出窗体,他们在打开前都需要获取window的width和height属性,那么我们可以通过一个openWin方法实现对两者的调用。
1
2
3
4
5
6
7
8
9
10
11
var modal = function ( ) {}
var pop = function ( ) {}
var openWin = function (mode ) {
var width = window .width;
var height = window .height;
if ('modal' == mode) {
new model(width, height);
} else if ('pop' == mode) {
new pop(width, height);
}
}
工厂方法模式 在上述的模式中有这样一个小缺陷,比方说当系统中新增了一个类dialog,此时我们不仅需要写dialog相关的构造放,还需要在openWin中的判断多加一条,这样静态的方法似乎显得不是很灵活。
而工厂方法模式比之前的简单工厂模式进一步的抽取了共性,不仅是通过一个方法的调用获得两种对象(统一入口),而且要实现两种对象可以通过同一个类(即工厂类)new出来。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var Factory = function (type, content ) {
if (this instanceof Factory) {
var s = new this [type](content);
return s;
} else {
return new Factory(type, content);
}
}
Factory.prototype = {
'modal' : function ( ) {}
, 'pop' : function ( ) {}
, 'dialog' : function ( ) {}
}
抽象工厂模式 抽象工厂模式
通过对类的工厂抽象使其业务用于产品类簇的创建,而不负责创建某一类产品的实例。 比如在上面的工厂方法中,modal类还分为smallModal和bigModal两种子类,他们都有一个共同的属性type,那我们再把他们的共性抽取出来,作为一个抽象类,不用于实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
var WinFactory = function (subType, superType ) {
if (typeof WinFactory[superType] === 'function' ) {
function F ( ) {};
F.prototype = new WinFactory[superType]();
subType.constructor = subType;
subType.prototype = new F();
} else {
throw new Error ('未创建该抽象类' );
}
}
WinFactory.modal = function ( ) {
this .type = 'modal' ;
}
WinFactory.modal.prototype = {
show : function ( ) {
return new Error ('抽象方法不能调用' );
}
}
var smallModal = function ( ) {
}
WinFactory(smallModal, 'modal' );
smallModal.prototype.show = function ( ) {
return 'show' ;
}
var modal = new smallModal();
console .log(modal.show());
console .log(modal.type);