javascript高质量代码(三)
最近在看《编写高质量代码-web前端修炼之道》,写了3篇博客,写写感想。
第一篇写了关于javascript封装以及模块化插件设计。
第二篇写了关于javascript面向对象思想以及原型和构造器。
第三篇主要写关于javascript的编写风格以及细节设计问题。
一、全局变量、全局函数
如果是很多人一起开发一个项目,那么就会造成很多的重命名的事件。这个时候就要一个局部函数,替换全局函数。
假设,程序员A写了段代码:
function a(){
var a="a is in function a(), writed by B";
alert("It's writed by A!!");
}
然后程序员B写了端代码:
function a(){
var a="a is in function a(), writed by B";
alert("It's writed by B!!");
}
如果我想要在一个页面同时包含这个两个函数,那么很简单,我们要用到匿名函数。
/*=========下面是A写的==========*/
(function a(){
var a="a is in function a(), writed by B";
alert("It's writed by A!!");
})();
/*=========下面是B写的==========*/
(function a(){
var a="a is in function a(), writed by B";
alert("It's writed by B!!");
})();
//它们不会互相影响
但是,如果我想要在A写的函数和B写的函数间传值,那么要怎么办?全局变量?可是一般最尽量不要用全局变量。
那就建个数组,造个对象,存放数据。
var global={ };
/*=========下面是A写的==========*/
(function a(){
global.A.a="a is in function a(), writed by B";
global.A.b=function(){alert("It's writed by A!!");};
})();
/*=========下面是B写的==========*/
(function a(){
global.B.a="a is in function a(), writed by B";
global.B.b=function(){alert(global.A.a);};
//return alert("alert("It's writed by A!!");
//这样就实现了匿名函数间传值,又防止了命名冲突
})();
这样子看起来是不是有些像prototype原型样式了。
var A;
A.prototype.a=function(){ };
A.prototype.b=function(){ };
A.prototype.c=function(){ };
写个封装函数吧,不然每次都要写一大堆。
var globale={ };
global.namespace=function(str){
var arr = str.split("."), o=global;
for(i=(arr[0] == "global") ? 1 : 0 ; i<arr.length; i++){
o[ arr[ i ] ] = o[ arr[ i ] ] = { };
o=o[ arr[ i ] ];
}
};
/*===========测试===========*/
global.namespace("A.start");
global.namespace("A.end");
global.A.start=function(){ alert("test:global.A.start") };
global.A.end=function(){ alert("global.A.end") };
二、函数入口
javascript是种脚本语言,浏览器执行渲染工作,javascript加载到哪一行,就渲染哪一行的语句,所以js的排放位置很重要,js的函数入口也很重要。
function A(){
alert("just test");
}
var B = function(){
alert("just test");
}
其实这两个函数都是一样的结果,但是,函数的意义不一样。当函数加载进来,就会直接执行A();然而函数B要调用。
- 用window.onload监听,会在网页元素全部加载完毕后触发onload事件。
- 用init();在DOMReady加载。
DOMReady只判断节点是否加载完毕,所以触发速度比window.onload快。
DOMReady不是原生的Javascript事件,要通过就是框架调用。
三、扩展原型函数
javascript是基于原型的语言,但是,并不是所有函数都要new实例化。
在js里面却没有each,clone等函数,所以我们可以拓展,重写内置类行为:
Array.pototype.each=function( callback ){
for(var i=0; i<this.length; i++)
callback( this[ i ], i );//对每个对象实行回调函数
}
Array.pototype.clone=function(){
var o = [];
this.each(function (k, v){
o[ k ] = v;
});
return o;
//我感觉我在写jquery的内核函数了。。
}
并且,还可以扩展内置类了。所有类的祖先都是在Object里面。
Object.prototype.test=function(){
return this.value;
};
/*==========测试=========*/
var xiaocao={ };
xiaocao.value="小草是帅哥";
alert(xiaocao.test());
//return 小草是帅哥;
四、改变DOM
-
方法一:
<div class="test" id="test">测试</div> <script> document.getelementById("test").style="font-size:20px;"; </script>
不实用。
-
方法二:
<style> class_name:{font-size:30px;} </style> <div id="test">测试</div> <script> var node = document.getelementById("test").style="font-size:20px;"; node.className="class_name"; </script>
-
方法三:
<script> function addStyle(str){ var style_node = document.creatElement("style"); style_node.type="text/css"; if (style_node.styleSheet ){ style_node.styleSheet.cssText = str; }else{ style_node.innerHTML = str; } document.getElementByTagname("head")[0].appendChild(style_node); } /*==============可以调用了============*/ addStyle("#test{font-size:30px;}"); </script>
获取节点的属性:
<div id="test" nick_name="xiaocao"></div>
<script>
var node=document.getElementById("test");
function(){
alert(node.nick_name);
//IE==>>xiaocao
//firfox==>>null
alert(node.getAttribute);
//IE&&firfox==>>xiaocao
}
</script>
也就是说,自定义标签属性,最好用attribute节点访问。
五、看看自己究竟写了什么恶心的代码:
其实,让我们来看个几个我以前写代码风格的例子,就会发现,一些问题。
function count_keys(symbol){
var key;
var _key=localStorage.getItem("result1");
var _key_=localStorage.getItem("result2");
var key_=localStorage.getItem("result3");
if(symbol.slice(0,1)==symbol.slice(1))//符号为+ +,- -,x x
key=count(count(_key,_key_,symbol.slice(0,1)),key_,symbol.slice(1));
if(symbol.slice(0,1)==1 && symbol.slice(1)==0 || symbol.slice(0,1)==0 && symbol.slice(1)==1)//符号为- +;+ -
key=count(count(_key,_key_,symbol.slice(0,1)),key_,symbol.slice(1));
if(symbol.slice(0,1)==0 && symbol.slice(1)==2 || symbol.slice(0,1)==1 && symbol.slice(1)==2)//符号为+ x;- x
key=count(_key,count(_key_,key_,symbol.slice(1),symbol.slice(0,1)));
if(symbol.slice(0,1)==2 && symbol.slice(1)==0 || symbol.slice(0,1)==2 && symbol.slice(1)==1)
key=count(count(_key,_key_,symbol.slice(0,1)),key_,symbol.slice(1)); //符号为x + ; x -
return key;
}
看自己以前写的代码真觉得,很多废话,最主要的是,感觉逻辑性好差,构思一个代码段真的很难,高质量代码也好难,要先想好多逻辑性问题,列表,流程图,不然都是废话。
还有一点就是,参数逻辑性不强,每个函数的对接性不强,模式化基本没有。
var test=JSON.stringify(test);
var students = JSON.stringify(datas);
storage.setItem('data',students);
storage.setItem('xiaocao.test.1',test);
//var obj = storage.getItem('data');
var obj = eval( "(" + storage.getItem('data') + ")" );//将json转化为对象
console.log('数量是:'+obj[1]+obj[2]+obj[3]+obj[4]+'哈哈哈哈'+obj.num);
//console.log('名称分别是:'+obj.2);
全局变量很多,函数的封装性很差,没有模式化。总的来说,就是,功能实现了,但是,没头没脑想到什么写什么。
看几个例子:
- 腾讯alloy团队图像处理:alloy image
- 记录鼠标信息的页面:url:http://pure.rednoize.com/movelogger/
很喜欢腾讯alloy团队那种封装好的代码。
addEvent=function(selector, eventType, func){
var proName = "";
switch(true){
case /^\./.test(selector) :
proName = "className";
selector = selector.replace(".", "");
break;
case /^\#/.test(selector) :
proName = "id";
selector = selector.replace("#", "");
break;
default:
proName = "tagName";
}
document.body.addEventListener(eventType,function(e){
function check(node){
if(! node.parentNode) return;
if(node[proName] == selector){
func.call(node, e);
};
check(node.parentNode);
}
check(e.target);
}, false);
}
//这段超爱,后来,我就收藏了。
javascript进阶就到这里了。
接下来要做的事情就是准备后台了。先练熟python,然后用web.py和tornado.py框架做web。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。