(原创)javascript进阶(三)
javascript进阶(三)
小草的主博客:http://xiaocaoblog.diandian.com
最近在看《编写高质量代码-web前端修炼之道》,写了3篇博客,记下看的东西。
第一篇写了关于javascript封装以及模块化插件设计。
第二篇写了关于javascript面向对象思想以及原型和构造器。
第三篇主要写关于javascript的编写风格以及细节设计问题。
一、全局变量、全局函数 如果是很多人一起开发一个项目,那么就会造成很多的重命名的事件。这个时候就要一个局部函数,替换全局函数。
假设,程序员A写了段代码:
|
1
2
3
4
|
function a(){ var a="a is in function a(), writed by B"; alert("It's writed by A!!"); } |
然后程序员B写了端代码:
|
1
2
3
4
|
function a(){ var a="a is in function a(), writed by B"; alert("It's writed by B!!"); } |
如果我想要在一个页面同时包含这个两个函数,那么很简单,我们要用到匿名函数。
|
1
2
3
4
5
6
7
8
9
10
11
|
/*=========下面是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写的函数间传值,那么要怎么办?全局变量?可是一般最尽量不要用全局变量。
那就建个数组,造个对象,存放数据。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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原型样式了。
|
1
2
3
4
|
var A;A.prototype.a=function(){ };A.prototype.b=function(){ };A.prototype.c=function(){ }; |
写个封装函数吧,不然每次都要写一大堆。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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的函数入口也很重要。
|
1
2
3
4
5
6
|
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等函数,所以我们可以拓展,重写内置类行为:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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里面。
|
1
2
3
4
5
6
7
8
9
|
Object.prototype.test=function(){ return this.value; };/*==========测试=========*/var xiaocao={ };xiaocao.value="小草是帅哥";alert(xiaocao.test());//return 小草是帅哥; |
四、改变DOM
方法一:
|
1
2
3
4
|
<div class="test" id="test">测试</div><script> document.getelementById("test").style="font-size:20px;";</script> |
不实用。
方法二:
|
1
2
3
4
5
6
7
8
|
<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> |
方法三:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<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> |
获取节点的属性:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
<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节点访问。
五、看看自己究竟写了什么恶心的代码:
其实,让我们来看个几个我以前写代码风格的例子,就会发现,一些问题。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
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 xkey=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;- xkey=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;} |
看自己以前写的代码真觉得,很多废话,最主要的是,感觉逻辑性好差,构思一个代码段真的很难,高质量代码也好难,要先想好多逻辑性问题,列表,流程图,不然都是废话。 还有一点就是,参数逻辑性不强,每个函数的对接性不强,模式化基本没有。
|
1
2
3
4
5
6
7
8
|
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团队那种封装好的代码。
|
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
|
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。
夏日小草 2013/12/5 19:57:13


浙公网安备 33010602011771号