[TOC]
JavaScript高级程序设计
第一章 JavaScript简介
- 文档对象模型DOM:针对XML但经过扩展用于HTML的应用程序编程接口,把整个页面映射为一个多节点结构。
DOM不只是针对JavaScript的,很多别的语言也都实现了DOM。但在Web浏览器中,基于ECMAScript实现的DOM已经成为JavaScript的重要组成部分。 - 浏览器对象模型BOM
第二章 在HTML中使用JavaScript
2.1 script元素
1. 使用<!-- <script>元素嵌入JavaScript代码时,指定type属性,type="text/javascript"
2. <script></script>如果放在head中,则必须等到全部JavaScript代码都被下载解析和执行完成才开始呈现界面,所以现在很多都放在Body的最后面,从而感觉打开页面速度加快
3. defer属性,表明脚本在执行时不会影响页面构造,等整个页面都解析完毕后再运行
4. async 适用于外部脚本文件,告诉浏览器立即下载,但不保证按指定的先后顺序执行
5. < 来代替小于号(<)
###2.2 嵌入代码与外部文件
1. 引入JavaScript有两种方式:
- 让脚本与标记混合在一起
- 包含外部的JavaScript文件 将src属性设置为指向相应文件的URL
##第三章 基本概念
###3.4 数据类型 Undefined Null Boolean Number String Object
1. 可以用typeof操作符来检测给定变量的数据类型
alert(typeof(message));
2. 非数值转换为数值:
Number() 【可以用于任何数据类型】
parseInt() 、parseFloat() 【专用于把字符串转换成数值】
###3.5 操作符
1. 一元操作符(只能操作一个值的操作符)如++ -- + -
在对非数值应用一元加操作时,该操作符会像Number()转型函数一样对这个值执行转换,即为:布尔值false 和 true 会被转换为0和1,字符串会被解析;
对象则是先调用valueOf()或 toString()方法
2. 位操作符
NOT(按位非)
AND(按位与)
XOR(按位异或)
左移(<<)[右填0,相当于乘2]
有符号右移(>>)[保持符号位,相当于除2]
无符号右移(>>>)[正数相同,负数非常大]
3. 布尔操作符 NOT AND OR
4. 乘性操作符 * / %
5. 加性操作符 + -
6. 关系操作符 < > <= >=
7. 相等操作符 == != ===(全等,两操作数未经转换就相等的情况下返回true)
8. 条件操作符 variable = boolean_expression ? true_value : false_value
9. 赋值操作符 = *= /= %= += -= <<= >>= >>>=
10. 逗号操作符 ,
###3.7 函数
1. 函数内可以通过arguments来访问这个参数数组,从而获取传递给函数的每一个参数
2. Array.prototype.slice.call先将其转为数组。
3. 函数定义不存在重载,如果一个名字定义了两次,则是后面一个
##第四章 变量、作用域和内存问题
###4.1 基本类型和引用类型的值
1. 基本类型值: 简单的数据段 Undefined Null Boolean Number String 【固定大小,保存在栈内存中】
引用类型值: 多个值构成的对象 【保存在堆内存中】==>实际上不是对象本身,而是一个指向对象的指针
2. 确定一个值是哪种引用类型,使用instanceof
###4.2 执行环境及作用域
1. 延长作用域链
全局环境 局部环境
1. try-catch语句
2. with语句
将指定的对象添加到作用域链中
2. 没有块级作用域
声明变量会自动添加到最接近的环境中。
先在局部变量中找,层级向外找该标识符,即为若局部环境中存在同名标识符,就不会使用位于父环境中的标识符。
###4.3 垃圾收集
1. 自动垃圾收集机制,无需开发人员关心内存分配和回收机制
2. 两种自动垃圾收集算法:标记清除、引用计数
1. 标记清除
2. 引用计数
##第五章 引用类型
###5.1 Object类型
1. 建议使用.来访问属性,除非属性名中含有" "空格
###5.2 Array类型
1. 检测数组
1. instanceof
arr instanceof Array
假定单一的全局执行环境 若网页包含多个框架,世界存在两个不同的全局执行环境...
2. Array.isArray(arr)
2. 转换方法
toLocaleString() 返回数组中每个值的字符串拼接而成由逗号隔开的字符串
toString() 返回数组中每个值的字符串拼接而成由逗号隔开的字符串
alert(arr)默认调用toString()方法
valueOf() 返回数组中每个值的字符串拼接而成由逗号隔开的字符串
join("|") 可以使用不同的分隔符来构建这个字符串
3. 栈方法
push() pop()
4. 队列方法
shift() 获得数组中的第一项
unshift() 在数组前端添加任意几项
5. 重排序方法
reverse() 对数组的顺序进行反转,也是排好序的
sort() 默认小值放前面
```
function compare(value1,value2) {
if(value1<value2) {
return -1;
}else {
return 1;
}
}
values.sort(compare)
```
或者直接values.sort(value2-value1);
6. 操作方法
concat() 复制原数组,并添加新的参数,返回新数组
参数:一或多个数组
var arr = ["a","b"];
var arr2 = arr.concat("c",["d,"e]);
//arr2 :["a","b","c"÷,"d","e"];
slice() 基于当前数组,返回数组
一个参数:返回从该参数指定位置到数组末尾的所有项
两个参数:返回起始和末尾位置之间的一项,但不包括末位位置项,若参数为负数,则为数组长度加上该负数的位置
arr.slice() //[0,end]
arr.slice(begin) //[begin, end]
arr.slice(begin,end) //[begin,end)
splice()
删除:两个参数,要删除的第一项的位置、删除项数
插入:三个参数,起始位置、0(删除项数)、要插入的项(可插入多个,为第四、五个参数)
替换:三个参数,起始位置、删除项数、要插入的任意项数, 会先删除,再插入
7. 位置方法
indexOf() 两个参数:要查找的项,查找起点的索引(可选) 从数组开头向后查
lastIndexOf() 两个参数:要查找的项,查找起点的索引(可选) 从数组最后向前查
8. 迭代方法
两个参数:每一项上运行的函数、运行该函数的作用域对象(可选,默认this)
函数有三个参数(数组项的值、该项所在数组中的位置、数组对象本身)
都不会修改原数组的值
every() 每一项运行给定函数,若该函数对每一项都返回true,则返回true
filter() 每一项都运行给定函数,返回该函数会返回true的项组成的数组
forEach() 每一项都运行给定函数,无返回数据
map() 每一项都运行给定函数,返回每次函数调用的结果组成的数组
some() 每一项都运行给定函数,若函数对任一项返回true则返回true
9. 缩小方法
两个参数:每一项上调用的函数、作为缩小基础的初始值(可选)
函数有四个参数:前一个值、当前值、项的索引、数组对象
reduce() 从前向后遍历 每次遍历完的结果返回给前一个值参数
reduceRight() 从后向前遍历
###5.3 Date类型
1. 1970年1月1日零时开始的毫秒数
2. Date.parse() 接收一个表示日期的字符串参数,返回相应日期的毫秒数
四种日期格式: 6/13/2017
January 11.2018
Tue May 15 2018 00:00:23 GMT-0700
YYYY-MM-DDTHH:mm:ss.sssZ
若不是日期,则返回NAN
3. Date.UTC() ...
4. 日期格式化方法
toDateString()
toTimeString()
toLocaleDateString()
toLocaleTimeString()
toUTCString()
###5.4 RegExp类型 支持正则表达式
1. var expression = / pattern / flags
flags: g 表示全局模式; i 表示不区分大小写模式; m 表示多行模式;
例: var pattern1 = /[bc]at/i;
var pattern2 = new RegExp("[bc]/at","i"); 两句完全等价
2. RegExp实例属性: global ignoreCase multiline lastIndex source
3. RegExp实例方法: exec() test()
4. RegExp构造函数属性
###5.5 Function类型
1. 没有重载:声明两个同名函数,后面的函数覆盖前面的函数
2. 函数声明: function sum(num1,num2){return num1+num2}
函数表达式: var sum = function(num1,num2){return num1+num2};
3. 函数可以作为参数传入函数中
4. 函数内部属性 arguments 保存函数参数
callee 指针,指向拥有这个arguments对象的函数
this 引用函数据以执行的环境对象,全局中为window
caller 保存调用当前函数的引用,若为全局作用域中调用当前函数,值为null
5. 函数的属性和方法
length 函数希望接收的命名参数的个数
prototype 保存引用类型所有实例方法,不可枚举的
apply() 两个参数,一个是其中运行函数的作用域,一个是参数数组。
call() 与apply()
功能相同,第一个参数也是this,后面的参数,直接传给函数
bind() 创建一个函数实例,其this值会被绑定给bind的参数
toLocalString()
toString()
valueOf() 这几个返回函数代码
###5.6 基本包装类型 (Boolean Number String)
1. Boolean
2. Number
3. String类型
1. 字符方法
charAt(2) 返回给定位置字符
charCodeAt(1) 返回给定位置字符编码
2. 字符串操作方法
concat() 将一个或多个字符串拼接
slice() 创建新字符串 两个参数:字符串开始位置、结束后一个位置
substr() 创建新字符串 两个参数:字符串开始位置、结束后一个位置
substring() 创建新字符串 两个参数:字符串开始位置、字符串长度
3. 字符串位置方法
indexOf()
lastIndexOf()
4. trim()方法 创建字符串副本,从一个字符串的两端删除空白字符
5. 字符串大小写转换方法
toLowerCase() toLocaleLowerCase()
toUpperCase() toLocaleUpperCase()
6. 字符串的模式匹配方法
match() [只接受一个参数,要么是正则表达式,要么是RegExp对象]
返回数组
search() [返回出现的索引]
replace() 两个参数:RegExp、字符串/函数
7. localeCompare()方法 比较字符串
8. fromCharCode()方法
9. HTML方法
###5.7 单体内置对象 (开发人员不必显式地实例化内置对象,因为已经实例化了)
1. Global对象
1. URI编码方法
encodeURI() encodeURIComponent() decodeURI() decodeURIComponent()
2. eval()方法 完整的ECMAScript解析器,只接受一个参数,为JavaScript字符串代码
3. Global对象的属性
4. window对象
2. Math对象
1. Math对象的属性
2. min()和max()方法
3. 舍入方法
4. random()方法
5. 其他方法
##第六章 面向对象的程序设计
###6.1 理解对象
1. 属性类型(数据属性、访问器属性)
1. 数据属性
包含一个数据值的位置,这个位置可以读取和写入
[Configurable: true][Enumerable: true][Writable: true][Value: undefined] 默认值必须使用Object.defineProperty()方法才能修改
2. 访问器属性
不包含数据值,包含一对getter和setter函数
[Configurable: true][Enumerable: true][Get: undefined][Set: undefined] 默认值必须使用Object.defineProperty()方法定义
2. 定义多个属性
Object.defineProperties() 方法 可以一次定义多个属性
Object.defineProperty(obj, prop, descriptor)
obj 需要定义属性的对象。
prop 需被定义或修改的属性名。
descriptor 需被定义或修改的属性的描述符。
var o = {}; // 创建一个新对象
// 在对象中添加一个属性与数据描述符的示例
Object.defineProperty(o, "a", {
value : 37,
writable : true,
enumerable : true,
configurable : true
});
3. 读取属性的特性
Object.getOwnPropertyDescriptor()
两个参数:属性所在的对象、要读取器描述属性名称
###6.2 创建对象
1. 工厂模式
function cratePerson(name,age,job) {
var o = new Object;
o.name = name;
...
return o;
}
var person1 = createPerson("zhang",12,"doctor")
var person2 = createPerson("li",14,"nurse")
未解决怎样知道一个对象的类型
2. 构造函数模式
function Person(name, age, job) {
this.name = name;
...
}
var person1 = new Person("li",14,"doctor")
new操作符以下4个步骤:
1. 创建一个新对象
2. 将构造函数的作用域赋给新对象(因此this指向了这个新对象)
3. 执行构造函数中的代码
4. 返回新对象
若不使用new,则直接添加到window上
缺点:每个方法都要在每个实例上重新创建一遍
修正:将函数写在外面:
然后内部用:this.sayName = sayName
function sayName() {
alert(this.name);
}
3. 原型模式
function Person(){
}
Person.prototype.name ="li";
...
Person.prototype.sayName = function() {
alert(this.name)
}
var person1 = new Person();
1. 使用prototype属性对其属性进行赋值和定义,构造函数变为空
2. 新函数都会有自身的prototype属性,属性指向函数的原型对象
3. Array.prototype 可以访问器所有的默认方法引用(同样适用于Object String)
4. 组合使用构造函数模式和原型模式
5. 动态原型模式 构造函数中使用if语句,判定存在与否,是否定义某函数属性
6. 寄生构造函数模式
7. 稳妥构造函数模式 安全环境,不使用this、new
###6.3 继承 【只支持实现继承,不支持接口继承】
每一个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针
1. 原型链
1. 所有引用类型默认都继承了Object
2. 继承:SubType.prototype = new SuperType()
通过创建SupeType的实例并将实例赋值给SubType.prototype实现的
new操作符以下4个步骤:
1. 创建一个新对象
2. 将构造函数的作用域赋给新对象(因此this指向了这个新对象)
3. 执行构造函数中的代码
4. 返回新对象
3. 默认的原型
为Object,所有的Prototype都是继承了Object
4. 缺点:
1. 包含引用类型值的原型
如:superType包含的属性,subType的所有实例都包含相同的内容
2. 在创建子类型的实例中,不能像构造函数中传递参数
2. 借用构造函数
子类型构造函数的内部调用超类型构造函数
function SuperType(name) {
this.name = name;
}
function SubType() {
SuperType.call(this,"li") //继承了SuperType,同时传递了参数
this.age = 29;
}
缺点:
方法都是在构造函数中调用,函数无任何复用
3. 组合继承
使用原型链实现对原型属性和方法的继承,而通过构造函数来实现对实例属性的继承
function SuperType(name) {
this.name = name;
this.colors=["red"...];
}
SuperType.prototype.sayName = function() {
alert(this.name)
}
function SubType(name,age) {
//继承属性
SuperType.call(this,name)//原型属性
this.age = age//自身属性
}
//继承方法
SubType.prototype = new SuperType();
SubType.prototype.sayAge = function() {
alert(this.age);
}
原型链和借用构造函数组合一起
缺点:调用两次超类型构造函数:SuperType
4. 原型式继承
Object.create(person)方法,有一个对象作为另一个对象的基础
两个参数:第一个为原对象
第二个为:自身属性
5. 寄生式继承
创建一个劲用于封装继承过程的函数,然后用某种方式来增强对象
缺点:不能函数复用
6. 寄生组合式继承
将那两个函数封装为一个
##第七章 函数表达式
###7.1 递归
###7.2 闭包 【有权访问另一个函数作用域中的变量的函数】
1. 闭包与变量 [javascript_problem_1]
2. 关于this对象
3. 内存泄露
###7.3 模仿块级作用域
###7.4 私有变量
1. 静态私有变量
2. 模块模式
3. 增强的模块模式
##第八章 BOM
###8.1 window对象
全局作用域
窗口位置:
IE Safari Opera Chrome:screenLeft screenTop
Firefox:screenX screenY
moveTo(x,y) 将窗口移动到一个新位置,新位置的x,y坐标 —|
moveBy(x,y) 水平和垂直方向上移动的像素数 _| 可能被浏览器禁用
窗口大小:
innerWidth innerHeight 页面视图区大小(减去边框宽度)
outerWidth outerHeight 浏览器窗口本身尺寸
document.documentElement.clientWidth/clientHeight 保存页面视口信息
调整浏览器窗口大小(默认禁用):resizeTo() resizeBy()
导航和打开窗口:
window.open() 打开一个新浏览器窗口
4个参数:要加载的url、窗口目标、一个特性字符串、一个表示页面是否取代浏览历史记录中当前加载页面的布尔值
1. 弹出窗口 window.open("http://www.baidu.com","baidu","height=400,width=300,top=10");
2. 安全限制
3. 弹出窗口屏蔽程序 badu == null 或者使用try{}catch(){}
间歇调用和超时调用:
1. setTimeout(要执行代码,以毫秒表示的时间) 返回一个调用ID,可使用claerTimeout(id)来取消
JavaScript为单线程语言,过了setTimeout时间后,将对应要执行代码添加到任务队列中。若队列为空,则执行该代码。
2. setTnterval(执行代码,时间) 也返回一个调用id 可使用clearInterval(id)来取消
系统对话框
alert()
confirm()
prompt()
###8.2 location对象
既是window对象的属性,又是document对象的属性:window.location=document.location
hash host hostname href pathname port protocol search
查询字符串参数:location.search()
位置操作:
location.assign("http://www.baidu.com");
location.href ="http://www.baidu.com";
location.hash/search/hostname/port
location.replace("http://www.baidu.com"); 不会再历史记录中生成新记录
reload() 重新加载当前显示的页面。可能从缓存中加载,如果添加true参数,就是从服务器重新加载
###8.3 Navigator对象
通常用于检测浏览器类型
userAgent
检测插件:
plugins 数组每一项都包含:name description filename length
每个插件对象本身是一个MimeType对象数组
IE中检测插件:ActiveXObject(name)检测,name为COM对象的唯一标识符
集合有refresh()方法,若传入tre参数,则重新加载整个页面,否则只会更新plugins集合
注册处理程序
MIME类型:application/rss+xml、applcation/atom+xml、application/vnd.mozilla.maybe. feed
RSS ATOM feed
###8.4 screen对象
外部显示器信息
###8.5 history对象
go()在用户历史记录中任意跳转
back()后退
forward()前进
length属性 保存的历史记录的数量
##第九章 客户端检测
###9.1 能力检测
不是识别特定的浏览器,而是识别浏览器的能力
检测是否有sort方法,要使用typeof sort == "function" 来判断是否函数
###9.2 怪癖检测
识别浏览器的特殊行为
###9.3 用户代理检测
通过检测用户代理字符串来确定实际使用的浏览器 Navigator.userAgent
电子欺骗:浏览器通过在自己的用户代理字符串中添加一些错误信息,达到欺骗服务器的目的
1. 识别呈现引擎:IE Gecko WebKit KHTML Opera
2. 识别浏览器
3. 识别平台:Windows Mac Unix
4. 识别Windows操作系统
5. 识别游戏设备
6. 识别游戏系统
##第十章 DOM
IE中所有的DOM对象都是以COM对象的形式实现的,因此与原生JavaScript对象的行为或活动特点不一致。
###10.1 节点层次
1. Node 类型
nodeType属性:
1:ELEMENT_NODE
2: ATTRIBUTE_NODE ...
nodeName【元素标签名】 、nodeValue 【null】属性
chlidNotes属性 和 NodeList对象
var arrayOfNodes = Array.prototype.slice.call(someNode.childNodes,0);//将NodeList转换为数组
parentNode属性
firstChild lastChild
appendChild()
向childNodes列表末尾添加一个节点,并返回新增节点,若本来就有该节点,则从原来位置移动到新的位置
insertBefore(要插入节点,作为参照节点)
放在某个特定的位置上
replaceChild()
替换
removeChild()
移除节点
cloneNode()
接收一个布尔值参数,表示是否执行深复制
2. Document 类型
HTMLDocument实例的document对象,document.childNotes 为<!DOCTYPE html> 和<html>
document
document.titile 只读
请求相关属性 HTTP头部
URL 页面完整URL 只读
domain 页面域名 可更改,为URL包含的一个子域名,但不同子域页面无法通过JavaScript通信
referrer 链接到当前页面的URL 只读,可为空
查找元素
若传入参数为:"*"则为获取所有,且一般不区分大小写
getElementById()
getElementByTagName()
namedITEM() 只返回第一个 如:
var myImage = images.namedItem("MyImage");
getElementsByName() 只有HTMLDocument类型才有的方法 返回为集合
特殊集合
document.anchors 文档中所有带name特性的<a>元素
cocument.forms 文档中所有的<form>元素
document.images 文档中所有的<img>元素
document.links 文档中所有带href特性的<a>元素
document.implementation
检测浏览器实现了DOM的那些部分功能
hasFeature(要检测DOM功能的名称,要检测DOM功能的版本号)
文档写入功能
write() 接收一个字符串,原样写入
writeln() 接收一个字符串,末尾添加一个换行符(\n)
"</script> -->" 不能直接写入,要写为"<\/script>",否则会被当做脚本块的结束
open() 打开网页输出流
close() 滚逼网页输出流
3. Element 类型
nodeType 为1 nodeName值为元素的标签名 nodeValue值为null parentNode值可能为Document或Element
1. HTML元素
所有的HTML元素都由HTMLElemnt类型表示
id 唯一标识符,对用户透明
title 元素附加说明信息
lang 语言代码,很少使用,用户透明
dir 语言方向,很少使用
className class特性对应
2. 取得特性
getAttribute("class")
"id"/"title"/"lang"/"dir"/自定义特性(最好加上data-前缀)
两类不能取得特性:style[CSS文本]、onclick[因为内容为JavaScript代码]
3. 设置特性
setAttribute("id","someOtherId")
removeAttribute()
4. attributes属性 【遍历元素特征】
atrributes属性中包含一系列节点,每个节点的nodeName是特性的名称,nodeValue是特性的值
getNamedItem(name) 返回nodeName属性等于name的节点
removeNamedItem(name) 从列表中移除nodeName属性等于name的节点
setNamedItem(node) 向列表中添加节点
item(pos) 返回位于数字pos位置处的节点
5. 创建元素
document.createElement("div");
4. Text类型
nodeType 为3 nodeName为”#text“ nodeValue 的值为节点所包含的文本 parentNode为Element 不支持子节点 可通过nodeValue的data属性访问Text节点中包含的文本
appendData(text) 将text添加到节点的末尾
deleteData(offset,count) 从offset指定的位置删除count个字符
insertData(offset,text) 从offset指定位置插入text
replaceData(offset,count,text) text替换从offset到offset+cout为止处的文本
splitText(offset) 从offset位置将当前文本节点分为两个文本节点
substringData(offset,count) 提取从offset到offset+count位置处的字符串
length属性:nodeValue.length、data.length
1. 创建文本属性 document.createTextNode()
2. 规范化文本节点 normalize()将包含多个文本节点的父元素的文本整合为单个文本
3. 分割文本节点 splitText() 将一个文本节点分为两个,分割位置为参数
5. Comment类型
nodeType 为8 nodeName为"#comment" ...
6. CDATASection类型
只针对于XML的文档,表示的是CDATA区域 继承自Text类型 nodeType为4 ...
7. DocumentType类型
不常用 nodeType 为0 nodeName为doctype的名称 HTML5 为 html
8. DocumentFragment类型
轻量级的文档,可以包含和控制节点,但在文档中没有对应的标记,可作为”仓库“使用,保存将来可能会添加到文档中的节点
9. Attr类型
不是DOM文档树的一部分 一般不需要直接访问特性节点
10.2 DOM操作技术
1. 动态脚本
动态创建<script>标签引入代码
2. 动态样式
加载完成后动态添加到页面中,使用DOM创建<link>元素,<style>
加载外部样式文件的过程是异步的,加载样式和执行JavaScript代码的过程没有固定的次序
3. 操作表格
Dom为<table><tbody><tr>等元素添加了一些属性和方法
...tbody.rows[0].cells[0]
4. 使用NodeList
每当文档结构发生变化时,会更新
一般尽量减少访问NodeList的次数,或者将其值缓存起来
网友评论