很长时间没有写前台代码了,突然想用js写个文件上传共通,结果遇到了各种各样的问题。
现在把问题和解决的办法记录一下。(有些还没有找到具体的原因)
1,利用extend(bool,{},item1,item2….)来深度拷贝对象,只是得到浅拷贝的结果。
测试语句:
var aa = {
bb:{
cc:"12"
}
}
var dd = $.extend(true, {}, aa);
var ee = $.extend(true, {}, aa);
//var dd = JSON.parse(JSON.stringify(aa));
dd.bb.cc="33";
ee.bb.cc="44";
console.log("aa=" + aa.bb.cc);
console.log("dd=" + dd.bb.cc);
console.log("ee=" + ee.bb.cc);
得到的结果是:
aa=44
dd=44
ee=44
预想的正确的结果是:
aa=12
dd=33
ee=44
PS:由于文件上传共通没有达到实际效果,才写了上面的简短代码来测试。后来发现这段测试代码可以专门用来测试jquery是否有效。
调查原因发现,自己的js和jquery有冲突,导致extend的深度拷贝无效。
问题代码是,在自己的js中有如下代码:
Object.prototype.getName=function() {
for (var a in window){
if (window[a]==this){
return a.toString();
};
}
}
后来改成如下就OK了。
function getName(obj){
for (var a in window){
if (window[a]==obj){
return a.toString();
};
}
}
另外,用上面的简短代码测试时,还发现js的导入顺序不一样,也会出现问题。
最初js的导入顺序是:
<script type="text/javascript" src="../js/jquery.js"></script>
<script type="text/javascript" src="../js/fileupload.js"></script>
会得到错误的结果。如果改为:
<script type="text/javascript" src="../js/fileupload.js"></script>
<script type="text/javascript" src="../js/jquery.js"></script>
运行的结果就正确了。
调整顺序后,虽然解决了深度拷贝问题,可我的文件上传共通其他地方又不对了。可能还是和jquery有冲突的原因。原因不明,郁闷~~~~
2,在自己的js中加入了一个jquery的静态方法,可在js中调用时显示这个方法没有定义。
js中定义的静态方法:
(function($){
$.extend({
getName:function(obj){
for (var a in window){
if (window[a]==obj){
return a.toString();
};
}
}
});
})(jQuery)
调用代码如下:
var images = {
init:function(id){
this.id = $.getName(this);
}
}
还没有调查出原因来,先写出来做个记录,等哪天弄明白了,再回头更新。
3,对于拷贝出来的对象的方法,在控件的事件中调用时,出现找不到该对象的错误。
js中定义的对象:
var fileupload = {
init:function(){
this.id = getName(this);
$("#" + this.id).append("<input type='file' οnchange='javascript:" + this.id + ".onchange();' value='' />");
},
onchange:function(){
}
}
jsp中拷贝对象的代码:
var newFileupload = $.extend(true, {}, fileupload);
newFileupload.init();
问题出在newFileupload没有定义成全局的对象,如果把var去掉改为:
newFileupload = $.extend(true, {}, fileupload);
就OK了。原因就是上面的拷贝语句写在一个叫mian的function里面了。所以成了一个局部变量。
看来要好好复习下js的基础了。
变量是所在对象的一个属性。函数也是对象。所有对象都是window的属性。
js的变量:
全局的:在javascript中定义的;在function中前面不加var定义的。
局部的:在function中前面加var定义的。
函数作用域(function scope):变量在声明它的函数体及函数体嵌套的函数体都是有定义的。函数的参数也是局部变量。
局部变量会取代全局的同名变量。
作用域链(scope chain):window -> window的function属性 -> window的function属性的function属性,以此类推。
js解释器在预编译javascript块时,首先找出非函数体内的所有var关键字,生成变量名标识并放入其所在作用域链中。执行函数体时,也是同样的处理。
在运行代码时,遇到变量,先从所属作用域链中查找,找到后取出来使用;若没有找到,继续在上一级作用域链中查找。直到顶层window还是没有找到,
则返回未定义。
4.1,(function($){….})(jQuery) 相当于:function fun($){…};fun(jQuery);
4.2,$(function(){}) 相当于:$(document).ready(function(){});
4.3,jQuery.extend(object);为扩展jQuery类本身.为类添加新的方法。
jQuery.fn.extend(object);给jQuery对象添加方法。
4.4,prototype.js是对原生对象的功能增强,多是扩充原生对象。
jquery.js是对原生语句的封装,多是构建自己的对象。
4.5,在自己写jquery插件时,应该都使用(function($){….})(jQuery)这种写法,因为我们不知道具体工作过程中是如何顺序引入各种js库的,而这种语句块的写法却能屏蔽冲突。