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 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;
}
|
看自己以前写的代码真觉得,很多废话,最主要的是,感觉逻辑性好差,构思一个代码段真的很难,高质量代码也好难,要先想好多逻辑性问题,列表,流程图,不然都是废话。 还有一点就是,参数逻辑性不强,每个函数的对接性不强,模式化基本没有。
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。