在看过许多大牛们的文章之后,大致对js的原理等有了一定的了解,现在来抛个砖希望各位点评。
要写出有效率的js代码先要牢记这一点,始终声明局部变量。全局变量在js中非常容易创建,然而坏处是会污染公共命名空间。相信前端开发的人都调用过别人的插件,良好的插件只暴露出一个对象名及其属性,插件的方法和变量全部封装在一个对象当中。如var a = 0,b = "string",c = function(){};就已经使用了三个变量名a,b,c,当封装成对象时则变成var obj = {a:0,b:"string,c:function(){}"},只需要调用obj.a~c即可达到相同的目的。
闭包也是被频频提及的东西,略过不谈,这里要讲一个容易出bug的例子,我在开发时写过以下一段代码 :
check:function(array){
for(var i = 0; i < 3; ++ i){
$(array[i]).on('click',function(){
$('#mainView').load("upload.php?type="+i);
});
}
}
一开始我以为不同标签响应的click事件分别对应参数type=1、2、3,结果发现这是type全部等于3,这是因为js是引用 i 而不是创建一个对象并将 i 赋值给它。修改方法有两种,代码如下:
①:check:function(array){
for(var i = 0; i < 3; ++ i){
(function(){
var j = i;
$(array[i]).on('click',function(){
$('#mainView').load("upload.php?type="+j);
});
})();
}
}
②:check:function(array){
for(var i = 0; i < 3; ++ i){
(function(j){
$(array[i]).on('click',function(){
$('#mainView').load("upload.php?type="+j);
});
})(i);
}
}
两种方法的原理是一样的,都是使用立即调用的方式创建了一个局部作用域,获得i的值而不是其引用,不过查阅资料后得知这种方式不能包含break和continue语句,因为这已经是属于函数外部,而且this和arguments的含义也会被改变。
复制字符串数组时同样如此:
var str = ["abc","cde"];
var str2 = str;//此时str2与str指向同一个数组
当时我犯了类似这样的一个错误: str2[1] = "";
str2[1] = str[0] + str[1]; // =>"abc";
正确的做法应该是
str2[1] = str[0] + str[1];//此时str[1]指向一个新的字符串对象