七、匿名函数
- 最有效的类型继承:寄生组合式
- 函数签名:函数名称+参数列表
- 匿名函数:即拉姆达函数。任何函数表达式都可认为是匿名函数(没有引用它们的确定的方式);
- 递归函数:递归函数应该始终使用arguments.callee来递归地调用自身,不要使用函数名(函数名可能会发生变化)。function factorial(num){ //经典的递归阶乘函数 if(num<=1){ return 1; }else{ return num*factorial(num-1); //return num*arguments.callee(num-1); }}//若之后factoral=null;再执行递归函数会报错 var temp=factorial;factoral=null;temp(4); //出错
- 闭包:有权访问另一个函数作用域中的变量的函数。当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了闭包。
- 作用域链:指向变量对象的指针列表,它仅引用变量对象
- 函数执行完毕后,局部活动对象会销毁,内存中仅保存全局作用域。但是,若闭包中的内部匿名函数的作用域链仍然引用外部函数的活动对象,则外部函数执行完毕该活动对象不会销毁,直到匿名函数被销毁(可解除对匿名函数的引用,来释放内存)。
- 闭包的作用域链:内部匿名函数活动对象 ->外部函数活动对象 -> 全局作用域(全局执行环境的变量对象)
- 闭包保存的是整个变量对象,若外部函数变量发生变化,则内部函数取得的是最后变化的内容。
- this对象:在运行时基于函数的执行环境绑定。在全局函数中,this==window,而当函数被作为某个对象A的方法调用时,this==A。匿名函数的执行环境具有全局性,因此其this对象通常指向window(除非通过call()或apply()改变)。
- 闭包的内存泄露:如闭包的作用域链保存着一个HTML元素,因为DOM的垃圾回收策略(引用计数),只要闭包的匿名函数存在,则该HTML元素永远不会被回收。
- 块级作用域:JS没有块级作用域,可以使用匿名函数模拟,例如:(function(){ //块级作用域})()这种技术通常在全局作用域中被用在函数外部,来限制向全局作用域中添加过多的变量和函数。
- 私有变量:JS没有私有成员的感念,所有对象属性都是公有的。但任何函数中定义的变量都可当成私有变量。私有变量包括函数的参数、局部变量、内部函数。
八、浏览器对象模型BOM
概述:BOM提供与浏览器的互操作性,没有标准的BOM实现或接口
- window:BOM的核心对象,表示浏览器的一个实例。即是JS访问浏览器窗口的接口也是ECMAScript规定的Global对象。
- 框架:每个框架都用于自己的window对象。
- top对象始终指向最高层的框架,可用top.frames[0]或top.frams["topFrame"]获取内部框架。
parent对象始终指向直接上层框架。
<frameset rows="160,*"> <frame src="frame.htm" name="topFrame"/> <frameset cols="50%,50%"> <frame src="left.htm" name=" leftFrame"/> <frame src="right.htm" name="rightFrame"/> </frameset> </frameset>
概述:
- 能力(特性)检测:不关心是什么浏览器而关心支持什么属性。
概述:文档对象模型是针对HTML和XML文档的一个API。
- 节点类型:ELEMENT_NODE(1),TEXT_NODE(3),DOCUMENT_NODE(9)
- 节点关系:firstChild,lastChild,previousSibling,nextSibling,parentNode。childNodes(childNodes[0]是引用childNodes.item(0))
- 节点操作:appendChild(),insertBefore(),replaceChild(),removeChild()
- 公有方法:所有节点均有的方法,cloneNode(true深复制/false),normalize()(删除空文本或者合并相邻文本节点)
- document:该对象是HTMLDocument(继承自Document)的一个实例。
- document.documentElement为html的引用。
- 其他属性:title设置文档标题;url完整的URL;domain域名(域名相同的框架页面可以互相访问JS对象);referrer来源页面的URL。
- 查找元素:getElementById();getElementsByTagName() (若返回images,images["myImage"]是引用images.namedItem("myImage")) ;getElementsByName()。
- 特殊属性集合:anchors所有带name特性的<a>元素;forms;images;links文档中所有带href的<a>元素。
十二、事件
- 事件流阶段:捕获->目标->冒泡。(DOM2级事件)
- 事件处理程序:响应某个事件的函数,或叫事件监听器。
- DOM0级:即传统方式,简单,跨浏览器。 btn.οnclick=function(e){//e.type=="click"//IE无e这个参数,window.event.type=="click"}
- DOM2级:使用注册和移除监听事件的方法。btn.addEventListener("click",function(e){ //this==btn},false);//第三个参数true捕获阶段调用、false为冒泡阶段调用。btn.removeEventListener("click",handler,false);//handler必须是明确的函数引用,若为匿名函数则无效。注:多播事件按添加顺序执行。IE的事件处理程序(只支持冒泡阶段):btn.attachEvent("onclick", function(e){ //this==window} );btn.detachEvent("onclick",handler);注:多播事件按添加顺序反向执行。
- DOM: body.οnclick=function(e){ e.currentTarget;//处理事件的元素,this== e.currentTarget==body e.target;//目标对象,若是按钮触发则是指该按钮 e.eventPhase;//事件阶段码(Integer),1.捕获,2.目标,3.冒泡 e.stopPropagation();//立即停止事件的传播,即取消进一步的捕获或冒泡 e.preventDefault();//取消事件的默认行为,仅当e.cancelable=true是有效。 //一旦事件处理程序完成,e对象就会销毁}
- IE:btn.οnclick=function(){ var e=window.event;//DOM0级方法添加事件函数时,event对象作为window的对象存在。 e. srcElement === this;//true}btn.attachEvent("onclick",function(e){ e.srcElement === this;//false e.cancelBubble = true;//取消事件冒泡 e.returnValue = false;//阻止事件的默认行为});
- UI事件:用户与页面元素交互时触发。
- 鼠标事件:鼠标
- 键盘事件:键盘
- HTML事件:浏览器窗口变化或发生特定的客户端/服务器交互时触发。
- 变动事件:底层DOM结构发生变化时触发。
- click:主鼠标单击或者回车键
- dbclick
- mousedown
- mouseout
- mouseover
- mouseup
- mousemove
- 客户区坐标:e.clientX、e.clientY。相对于浏览器可视区域。
- 屏幕坐标:e.screenX、e.screenY。相对于电脑屏幕的位置。
- load:window的load会在页面中的一切都加载完毕才触发。图片加载完毕在<img>触发。
- unload
- abort
- error
- select
- submit
- reset
- resize
- scroll
- focus
- blur
- 节点移除
- 节点插入
- 特性变化
- 文本变化
- 上下文菜单事件:contextmenu (全支持)
- 卸载前事件:beforeload (全支持)
- 鼠标滚轮事件:mousewheel(全支持)
- DOMMouseScroll事件:Firefox类似鼠标滚轮的事件
- DOMMContentLoaded事件:在形成完整的DOM数之后触发。(仅FireFox,Chrome,Safari3.1以上和Opera9以上支持)//对于不支持该事件的浏览器,建议如下面为页面中设置第一个超时调用(0毫秒)。即便如此仍无法保证一定早于load事件//“在当前JS处理完成后立即运行这个函数”,页面下载和构建只有一个JS处理过程,该过程结束会立即调用此超时调用 setTimeout(function(){ //在此添加事件处理程序},0);
- 就绪状态变化事件:readystatechange,IE和Opera支持,但效果不一
- 页面显示、隐藏时间:pageshow/pagehide,针对与FireFox和Opera的往返缓存。
- 事件委托:在DOM树中尽量最高层添加事件处理程序,内部元素的事件冒泡到这一个函数中处理。以解决事件过多产生的性能问题。mouseover和mouseout需计算元素的位置,故不适合事件委托。
- 移除事件处理函数:DOM中移除的元素中带有事件处理函数,若不移除函数则极可能无法垃圾回收。btn.οnclick=null;//移除事件处理程序
- 浏览器卸载页面前移除所有的事件处理函数
- DOM:document.createEvent(eventType)
- IE:document.createEventObject()返回通用的event对象
- 独有属性和方法
- acceptCharset:服务器能够处理的字符集,等价于HTML的accept-charset。
- action:接收请求的URL,等价于HTML的action特性
- elements:表单中所有控件的集合(HTMLCollection)。
- 取得表单域:form.elements[0]==form[0];form.elements["name"]=form["name"]。若有重复name则返回NodeList。
- enctype:请求的编码类型,等价于HTML的enctype。
- length:表单中的控件数量。
- method:要发送的HTTP请求类型,get、post。等价于HTML的method。
- name:表单的名称,等价于HTML的name。
- reset():将所有的表单域重置为默认值。form.reset()会触发reset事件。
- submit():提交表单。<input type="image" >与<button type="submit">按回车即会提交焦点下的表单。直接使用form.submit()不会触发submit事件。避免重复提交需监听submit事件(不要监听click)禁止按钮。
- target:用于发送请求和接收响应的窗口名称,等价于HTML的target。
- 公有表单域属性
- disabled:禁止当前域
- form:表单指针,只读
- name:域名称
- readOnly:是否只读
- tabIndex:tab序号
- type:域类型,如“checkbox”,“radio”
- value:域提交给服务器的值。文件域时为只读,包含文件在计算机中的路径。
- 公有表单域方法
- focus()
- blur()
- 公有表单域事件
- blur
- change:<input><textarea>失去焦点且value改变时触发;<select>选项改变时触发。
- focus
- 文本域
- 单行<input type="text" size="25" maxlength="50" value="初始值">显示25字符,输入最长50字符
- 多行<textarea rows="25" cols="5">初始值</textarea>没有指定最大字符的属性
- 读取和设置值:textField.value = "新的值"。最好不用DOM方法修改value,因其不一定能反映在DOM中。
- 选择文本:select(),选中域中所有文本。会触发select事件(Safari,Chrome除外)
- 读取选择的文本
- function getSelectedText(textbox){ if(document.selection){ return document.selection.creatRange().text;//IE }else{ return textbox.value.substring(textbox.selectionStart,textbox.selectionEnd); }}
- textbox.value = "Hello world!";//选择所有文本textbox.setSelectionRange(0,textbox.value.length);//"Hello world!"//选择前3个字符textbox.setSelectionRange(0,3);//"Hel"//选择第5到第7,不包括索引7,7-4=3个字符,类似于substring()的参数textbox.setSelectionRange(4,7);//"o w"//获取焦点,用户才能看见选择的文本textbox.focus();
- //IE代码var range = textbox.createTextRange();//创建范围对象range.collapse(true);//范围折叠到开始位置range.moveStart("character",4);//指定起点range.moveEnd("character",7-4);//指定终点range.select();//选择文本//获取焦点,用户才能看见选择的文本textbox.focus();
- 屏蔽字符
- 屏蔽所有按键:keypress事件里禁止默认行为
- 屏蔽部分按键://屏蔽非数字if(!/\d/.test(String.fromCharCode(charCode))&&charCode>9&&!e.ctrlKey){ //charCode为字符编码 //charCode>9用于兼容其他常用按键如上下键,退格和删除键,例如FireFox为0 //!e.ctrlKey不屏蔽ctrl与数字的组合键 //preventDefault(e),禁止默认行为}
- 操作剪贴板
- beforecopy/copy
- beforecut/cut
- beforepaste/paste
- 自动切换焦点
- 由<select><option>元素创建
- <select>元素,HTMLSelectElement类型的属性和方法
-
- type:"select-one","select-multiple"
- add(newOption,relOption):指定项之前插入新的项
- multiple:是否允许多选
- options:控件中所以<option>元素的HTMLCollection。
- remove(index):移除指定位置的选项。
- selectedIndex :保存选择项中的第一项的索引,无选中则为-1。可设置选中指定索引的选项(会取消已有的选项)。
- size:选择框中可见的行数。
- value:无选择项则为空串;有一选择项则为该项的value(若无value属性则为该项的显示文本);多选项则以第一项为准。
- <option>元素,HTMLOptionElement类型的属性和方法
- index: 选项 在options集合中的索引。
- label: 选项 的标签。
- selected:是否被选中,可设置为true选中该项。
- text: 选项 的文本。
- value:选项的值。
- selectbox.selectedIndex=0;//选择第一项,会反选已选的选择项。
- selectbox.options[0].selected=true;//多选类型时,不会反选已选的选项;单选类型时, 会反选已选的选项。
- for(var i=0, len=selectbox.options.length; i<len; i++){ // option.selected 循环遍历获取所有选择项 }
- DOM方式var newOption = document.createElement("option");newOption.appendChild(document.createTextNode("Option text));newOption.setAttribute("value", "Option value");selectbox.appendChild(newOption);//insertBefore()
- 构造函数//最佳方案var newOption = new Option("Option text","Option value");selectbox.add(newOption,undefined);//末尾追加
- DOM方式selectbox.removeChild(selectbox.options[0]);//移除第一项
- 自身函数selectbox.remove(0);
- 遗留机制selectbox.options[0]=null;
- 将一个选择框的选项移动到另一个选择框中selectbox2.appendChild(selectbox1.options[0]);//appendChild传入已有的元素会先从父节点selectbox1中移除它
- 在选择框中重新排序var optionToMove = selectbox.options[1];selectbox.insertBefore(optionToMove, selectbox.options[optionToMove.index-1]);//选项前移
- 浏览器错误报告
- 错误类型
- Error:基础错误
- EvalError:eval()异常
- RangeError:范围异常
- ReferenceError:未找到对象异常
- SyntaxError:eval("a++b"),eval执行错误的语法会抛出该错误
- TypeError:变量的类型不符合要求
- URIError:encodeURI()/decodeURI(),URI格式不正确。
- 错误处理try { //可能异常的代码 throw 12345; throw "Hi"; throw true; throw { name: "JS"}; throw new Error("It's Error");} catch (error) { //error.message } finally { //一定会执行的代码,即使try中包含return也会被忽略}
- 错误处理策略
- 重点关注的错误类型
-
- 类型转换错误
- 数据类型错误
- 通信错误
十五、JavaScript与XML
十六、E4X
十七、AJAX与JSON
十八、高级技巧
十九、客户端存储
二十、最佳实践