原书详情:
桑贝斯. JavaScript DOM高级程序设计[M]. 人民邮电出版社, 2008.
首先说一下我的亲身感觉,时代在进步,这本书中的观点其实已经和现在的一些观点起冲突了,比如本书一直在倡导的:
JavaScript是用来增强与用户的交互的.
注意,是增强,不是完成,所以需要保证,即使浏览器禁用JavaScript,网页也能正常交互.但是看看现在,Node.js还有React.js,JavaScript的作用不再是简单的增强交互.套用一句话,鬼知道JavaScript之后能做到什么程度.所以针对本书的内容,我不会全盘引用,而是有针对性的摘录一些.
至于为什么要刷这本书,是因为被老大喷,JavaScript基础这么差,去学什么高深的东西,先把底子打好,于是就开始刷这本书了.今天才刷了第一章,大大感叹自己底子是真的差.
第1章 遵循最佳实践
1.1 不唐突和渐进增强
没什么内容,可以直接忽略.
1.2 让JavaScript运行起来
最好不要使用内嵌式的将js代码写在网页中,而是写在一个一个js文件中,在需要时进行引用.
不要在超链接中使用如下形式的js调用:
<a href='javascript:window.location.href="#"'>这里超链接是使用js实现的</a>
<a hre="" onclick="functionName">这里在标签内部绑定了JS点击事件</a>
而是使用class和id进行事件绑定.
不要进行版本检测,常说要兼容各种浏览器,我是没有实际操作过,毕竟我是伪前端,书上的意思是不要针对各种浏览器做不同的处理,而是检测该浏览器是否支持该操作,如果支持,则运行该效果,如果不支持,则宁可直接放弃该效果.
模拟命名空间
这里直接贴一段代码:
(function(){
// 如果已有对命名空间 ADS 的占用,则清除该占用
if(!window.ADS){
window['ADS`]={}
}
// 定义一个函数,并将其保存进文档ADS命名空间下,名字就叫做function1
function function1(){}
window['ADS']['function1']=function1;
// 这里也是
function function2(){}
window['ADS']['function2']=function2;
})()
假设上述代码都保存在一个名为ADC.js
的文件中,当你想调用其中的function1
时,只需两步:
- 在页面中引入
ADC.js
- 以如下方式进行调用
ADC.function1()
.
这样的调用形式从外部看来,仿佛是调用在ADC
命名空间下的function1
函数.
该部分剩下的内容就是对其中函数的扩充,很有价值,而且是循序渐进的,很适合小白看.稍后我会把PDF版以百度云的形式分享出来的.
1.3 JavaScript语法中常见的陷阱
- 区分大小写
- 单引号和双引号
这里其实是我一直用错的地方,详细介绍一下:
var html='<a href="index.php">注意,是在单引号中嵌入双引号</a>';
以前一直是在双引号中嵌入单引号.....
其遵守的规则如下:
- 所有HTML属性值必须使用双引号括起来,比如a的href属性
另外还有一点,同样是上面的拼接html字符串,如果要换行,就使用字符串拼接的方式,这样能保证即使被第三方库编译也不会出错.
还有一点,JavaScript其实不强制要求你一定要写;
,比如下面的代码是能正确运行的:
alert(1)
alert(2)
alert(3)
但是最好还是写上,有一句名言:
要记住,维护你代码的人是个精神容易崩溃,且知道你家地址的人.
重载,JavaScript不支持重载,同一个名称的函数,js不会按照你传入参数的不同就调用不同的函数,相反,js会直接调用最后的函数,简单来说就是覆盖.
函数作用域
这个很重要!!!
先来看这段例子:
<div id="1">1</div>
<div id="2">2</div>
<div id="3">3</div>
<script type="text/javascript">
for(var i=1;i<3;i++){
var divObject=document.getElementsById(i);
divObject.addEventListener('click',function(){
alert(i);
});
}
</script>
这里为每一个div
绑定了一个单击事件,希望能输出不同的弹框,但是事实是,每一个div
输出的弹框都是一致的,都是3,至于原因,就是作用域,每个div
绑定的是事件都是一个匿名函数(闭包函数):
function(){
alert(i);
}
但是注意,在闭包函数中并没有定义参数i
,参数i
属于其上级函数,所以当该闭包函数找不到参数i
时,就向上级去寻找,那时i
由于for
函数已经递增到3了,所以每个div
点击后弹出的都是3.
这里要说明的是:当一个函数内部调用某个未在函数内部定义的参数时,就会向上去寻找.
迭代对象,简单来说就是当我们迭代
var divObjects=document.getElementsByTagName('div');
这样形式的返回值时,返回值的类型是NamedNodMap对象,可以像操作数组一样对其进行遍历,但是当使用遍历的另一种形式时,就会出现另外的参数:
页面源码:
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
js代码如下:
var divObjects=document.getElementsByTagName('div');
for (i in divObjects){
console.log(divObjects[i]);
}
运行结果:
其中会多出来几个参数:length,item,namedItem
,这几个参数都是NamedNodeMap
对象附加的几个参数,由于for
函数被调用到了.
要想去除掉这几个参数可以使用如下的调用形式:
var divObjects=document.getElementsByTagName('div');
for( i in divObjects ){
// 筛选掉额外元素
if(!divObjects.hasOwnProperty(i)){
continue;
}
// 这里就是div对象了
console.log(divObjects[i]);
}
关于hasOwnProperty()的介绍.
文件原文下载地址
文件扫描版百度云下载地址:
链接: https://pan.baidu.com/s/1geBMG0N 密码: 5wcc