JavaScript总结
JavaScript的作用十分巨大,在Web开发中占据了重要的位置,今天来总结一下最近学习的JavaScript的内容。
一,基本数据类型
Number:不区分整型和浮点型,统一用Number表示。
String(字符串):用单引号或双引号括起来的任意文本。
注:推荐在JS中用单引号表示字符串,因为在HTML标签行间样式中一般用双引号设置属性,这样做能做区分。
Boolean(布尔类型):true|false。
Null:null
Undefined:undefined---一般表示数据未定义
注:typeof(undefined)会返回object,这实际上是 JavaScript 最初实现中的一个错误,然后被 ECMAScript 沿用了。现在,null 被认为是对象的占位符,从而解释了这一矛盾,但从技术上来说,它仍然是原始值(引用W3C)。
Object:JavaScript的对象是一组由键-值组成的无序集合。
二,数组
数组在JS中应用十分广泛,作用也很强大,所以单独抽出来介绍。
1)数组属于Object类型的数据。
2)定义数组的两种方式
①new Array(1,2,3);
②var array=[1,2,3];
两种方式均可以定义数组,不过第一种似乎更符合面向对象定义对象的风格。
3)数组的length属性
length属性标志着这个数组中存在的元素的个数,通过array.length可以得到数组的长度。
另外我们随时可以通过length属性的值改变数组的长度,设置为0可以快速清空数组元素,也可以设置大于原数组长度的值,扩充数组(自动用undefined填充)。
4)数组的常用方法
①数组的添加和删除元素
push();向数组的尾部添加元素。
pop();弹出数组的尾部元素。
-->push()和pop()就是栈的操作,如果数组只允许使用这两个方法,数组就变成了和栈一样的数据集合。
shift();弹出数组头部的元素。
unshift();向数组头部添加元素。
-->如果数组只允许使用push()和shift()方法,那么数组就变成了队列一样的数据集合。
②splice()方法
这个方法从数组中添加/删除项目,然后返回被删除的项目。
splice(起始索引,长度);删除从起始位置开始指定长度的元素并返回删除的元素集合。
splice(起始索引,长度,添加元素1,添加元素2...);先删除从起始位置开始指定长度的元素然后从起始位置添加新的元素最后返回删除的元素集合(依然返回删除的元素)。
③concat()方法
方法用于连接两个或多个数组。该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。
var a1 =new Array(1,2,3,4,5); var a2=new Array(10,20); var a3=a1.concat(a2); alert(a1);//1,2,3,4,5 alert(a2);//10,20 alert(a3);//1,2,3,4,5,10,20
可以看出concat对原数组不会有任何影响。
④join()方法
join() 方法用于把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的。
var a1 =new Array(1,2,3,4,5); var a2=a1.join('-'); alert(a1);//1,2,3,4,5 alert(a2);//1-2-3-4-5
join和concat一样不会影响原数组。
⑤sort()方法
sort()方法很常见,就是一个排序的方法,但是JS数组自带的sort方法很不好用(默认的字符串排序),往往需要我们自己重写。
var a1 =new Array(12,111,524,24,5); a1.sort(); alert(a1);//111,12,24,5,524
默认的字符串排序,我们想使用自定义的排序规则怎么写?
var a1 =new Array(12,111,524,24,5); a1.sort(function(n1,n2){ if(n1<n2){return -1;} else if(n1>n2){return 1;} else {return 0;} //其实上面的代码可以直接写return n1-n2; }); alert(a1);//5,12,24,111,524
这里用到了匿名函数,和JAVA匿名函数类似。
⑥slice()方法
slice(start,end) 方法可从已有的数组中返回选定的元素。返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素。
三,事件
事件是与函数不同的概念,事件的发生往往是函数的调用触发条件。也就是说往往某个事件的触发,会导致一个或多个函数的调用,以便实现某种效果。
JS中的事件如下:
onblur:当元素失去焦点时触发。
onfocus:元素获得焦点。
onchange:当用户改变域的内容时触发。
onclick:点击某个对象。
ondbclick:双击某个对象。
onmousedown:鼠标某个按键被按下
onmouseup:鼠标某个按键被松开
onmousemove:鼠标移动
onmouseout:鼠标从某个元素移开
onmouseover:鼠标移动到某个元素上
onerror:当文档和图片加载错误。
onkeydown:键盘某个键被按下。
onkeyup:键盘某个键被松开。
onkeypress:键盘某个键被按下或按住。
onload:页面或图片加载完成。
onreset:重置按钮点击。
onresize:窗口或框架尺寸被调整。
onselect:文本被选中。
onsubmit:文本被提交。
onunload:用户退出页面。
事件被触发了当然要产生某种对应的结果,所以事件得和响应的元素绑定起来,如何绑定这些事件呢?
DOM0事件模型:
直接在dom对象上注册事件名称,就是DOM0写法,比如:
document.getElementById('button1').onclick=function(e){};
当然存在另一种写法:
document.getElementById('button1')['onclick']=function(e){}
事件被触发时,会默认传入一个参数e,表示事件对象,通过e,我们可以获取很多有用的信息,比如点击的坐标、具体触发该事件的dom元素等等。
[]的写法,也把js写活了,用字符串表示属性名称,可以在运行时动态绑定事件。灵活性得到极大的提升。
另外如果一个元素被同种事件注册两次,最后一次会覆盖第一次。
DOM2事件模型:
DOM2事件通过addEventListener和removeEventListener管理。
注册事件:addEventListener(事件名称,回调函数,捕获事件|冒泡事件);
document.getElementById('button1').addEventListener('click',function(){},false);
事件名称把on去掉,就是DOM2中的参数要求的名称。
最后个参数true代表捕获事件,false代表冒泡事件。
这里引进冒泡事件和捕获事件得解释,这里参考别人的解释。
某个元素触发了某个事件,最先得到通知的是window,然后是document,依次而入,直到真正触发事件的那个元素(目标元素)为止,这个过程就是捕获。
接下来,事件会从目标元素开始起泡,再依次而出,直到window对象为止,这个过程就是冒泡。
好了明白了捕获和冒泡事件,其实我感觉捕获和冒泡事件可以这样理解,这里举个几个例子。
div1是外层,div2是内层,a函数是弹出当前触发元素的ID。
document.getElementById('div1').addEventListener('click',a,true); document.getElementById('div2').addEventListener('click',a,true);
先弹div1再弹div2,很好理解,接下来:
document.getElementById('div1').addEventListener('click',a,false); document.getElementById('div2').addEventListener('click',a,false);
先弹div2再弹div1,也很好理解,再接下来:
document.getElementById('div1').addEventListener('click',a,false); document.getElementById('div2').addEventListener('click',a,true);
div2->div1
document.getElementById('div1').addEventListener('click',a,true); document.getElementById('div2').addEventListener('click',a,false);
div2->div1
好了,好像看出来是怎么回事了,也就是当一个事件触发的时候先是捕获事件得发生然后冒泡事件发送,也就是说这些事件都会发送,只是看你愿不愿意处理,true也就是处理捕获的事件,而false就是处理冒泡事件。
最后对于冒泡事件,如果内层和外层都是冒泡事件,点击了内层不希望外层弹出,可以设置阻止冒泡发生。
事件触发时,会默认传入一个event对象,前边提过了,这个event对象上有一个方法:stopPropagation,通过此方法,可以阻止冒泡,这样外层div就接收不到事件了。
removeEventListener("事件名称", "事件回调", "捕获/冒泡");删除注册的事件,必须和注册的时候参数一致。
四,this指向的对象
js中this真的很混乱,这里我想借用blue大神说的一句话,记住这句话this指向的谁就很清晰,这句话就是"方法属于谁,this属于谁"。
这句话反正目前看来,真的很对,这里写一个容易犯错的例子。
function a (){ alert(this); }
window.onload=function(){ document.getElementById('button1').onclick=a;//input对象 }
这个结果很正常但是如果写成下面这样
<input type="button" id="button1" value="ok" onclick="javascript:a();" ></input>
他弹出的是window对象,为什么呢?
很简单因为这样写在行间,调用的对象就是window.
五,AJAX技术
这里不总结了,专门写了一篇文章。
六,面向对象
JS中也是有面向对象的设计方式的,关于面向对象思想用过java的都清楚了,这里说JS怎么利用面向对象的。
首先有个原则,不能在系统对象中任意添加属性和方法,会覆盖已有方法。
使用面向对象,需要使用Object空白对象,这个对象可以任意添加属性和方法。
创建对象的方式:
1)工厂生产的方式(函数产生)
首先需要一个构造函数。
function createPerson(name,age){ var obj=new Object(); obj.name=name; obj.age=age; obj.showName=function (){ alert(this.name); } obj.showAge=function (){ alert(this.age); } return obj; }
可以看出来这个函数,相当于一个工厂,制作一个对象出来。
下面我们看看如何生产对象。
var obj1=createPerson('a',12); obj1.showName();//a var obj2=createPerson('b',15); obj2.showName();//b alert(obj1.showName==obj2.showName);//false
结果很正常,就是最后一个比较两个对象的方法的时候,他是false,也就是说不同对象的即使方法代码一样,产生的也不同,这样就导致了性能很低下。
其次,他不是传统的new对象的生成方式,有点不习惯。
所以为了解决这些缺点,就有了第二种产生对象的方式。
2)利用原型(prototype)
首先要知道什么是prototype?
还是借用blue大神的解释,解释的特别到位~~
在CSS中,class是给一组元素加样式,而行间样式是给一个元素加样式。
这里类比到JS上,prototype就是class,行间样式就是给对象加东西。
知道了prototype的大概意思,再来个例子就能明白了。
首先有两个原则
①构造方法加属性。
②原型加方法。
因此上面的代码可以改写为:
function createPerson(name,age){ this.name=name; this.age=age; } createPerson.prototype.showName=function (){ alert(this.name); } createPerson.prototype.showAge=function (){ alert(this.age); } var obj1=new createPerson('a',12); obj1.showName();//a var obj2=new createPerson('b',15); obj2.showName();//b alert(obj1.showName==obj2.showName);//true
这样就解决了new和方法不同的问题,感觉很好用。
上面介绍了面向对象产生对象的方式,下面说一下继承。
继承:
首先介绍一个方法call();
这个方法有个重要的作用,就是改变函数调用时候的this的值。
例如一个show函数,作用弹出this对象。
当使用show()时候,其实只是show.call()的简写。
完全可以写成show.call(1);这样的话弹出的this对象就变成了1。所有call可以改变this的值。
有了这个call()实现继承了。
function A() { this.value=12; } A.prototype.show=function(){ alert(this.value); } function B() { A.call(this) }
var obj=new B();
alert(obj.value);//12
通过这种方式就完成了属性的继承,注意是属性的继承,现在怎么实现方法的继承呢?
可以通过
B.prototype=A.prototype;
这样能实现A的方法继承给B但是有个一问题,那就是其实是把A的原型引用给了B,也就是B添加方法,A也会得到修改,所以不能这样。
所以可以通过遍历,复制的方式来继承方法。
for(var i in A.prototype){ B.prototype[i]=A.prototype[i]; }
这样就可以解决刚才的问题。
七,JS中的正则表达式
字符串的常用方法:
search();寻找字符
substring();截取字符串不包括结束位置
charAt();返回指定索引字符
split();分割字符串
然后介绍一下JS中如何使用正则表达式,因为之前写了篇JAVA正则表达式,这里不多写,只写怎么用。
正则表达式写法:
JS风格:var regular=new RegExp(规则,'i');//i忽略大小写
perl风格:/a/i i 忽略大小写 /a/g g找到全部
然后调用一些列的方法处理字符串即可。
八,其他
打开,关闭窗口
window.open(url);
window.close();
利用open实现运行JS的效果
document.write('');//写内容到页面
window.open('about:blank');//弹出空白窗口
open()第二个参数'_self','_blank'
var nwindow=open()返回新窗口的对象
nwindow.document.write(' ');
常用属性
window.navigator.userAgent;//当前浏览器版本信息
window.location;//当前窗口地址
尺寸及坐标
可视区尺寸
滚动距离:可视区距离边缘的距离
document.documentElement.clientWidth--可视区宽度
document.documentElement.scrollTop--滚动距离
IE6是body
offsetHeight;组件的高度
window.onscroll 滚动条事件
window.onresize 窗口改变事件
固定定位-fixed
position:fixed;
绝对定位-absolute
position:absolute;
系统对话框
警告框:alert()
确认框:confirm()返回值true|false
输入框:promot()返回值输入内容
JS中的Cookie
document.cookie;
设置Cookie
格式要求:名字=值
设置过期时间
expires=date;
删除cookie 设置过期时间为以前的时间即可。
JavaScript总结就先写到这里,以后需要添加再添加内容......