变量与函数声明
变量:变量就是用来储存数据(任何数据类型)的容器,这样脚本就可以通过变量的名称访问变量中
储存的数据,如果没有为变量赋值,变量会保存--undefined,例如:var age;(也叫变量声明) ;变量又可以分为
全局变量和局部变量。
函数声明:即定义函数的一种方式,另一种方式是函数表达式。函数声明的语法如下:
function name(参数)
{函数体}
函数声明最重要的特征就是函数声明提升,就是在执行函数体的代码前会优先读取函数声明,
这样函数声明可以放在调用的语句后面,例如:
hello();
function hello(){
alert("hello");
}
作用域
作用域:即变量存在的执行环境,作用域控制着变量和参数的生命周期。执行环境定义了变量或函数
有权访问的其他数据,每个执行环境都有一个变量对象,环境中定义的所有变量和函数都保存在这个对象中。
每个函数都有自己的执行环境,在执行代码时都会创建一个变量对象的作用域链,
作用域链本质上是一个指向变量对象的指针列表,他只引用但不包含变量对象。作用域链保证对执行函数有权
访问的所有变量和函数的有序访问,例如:
var rain = 1;
function rainman(){
var man = 2;
function inner(){
var innerVar = 4;
alert(rain);
}
inner(); //调用inner函数
}
rainman(); //调用rainman函数
查询变量x时,这段代码的三个作用域链对象依次是 inner、rainman、window
在函数体内部,局部变量的优先级比同名的全局变量高,内部环境可以通过作用域链访问所有的外部环境,但
外部环境不能访问内部环境中的任何变量和函数,在js中没有块级作用域(任何一对花括号中的语句集都属于一
个块,在这之中定义的所有变量在代码块外都是不能访问的,我们称之为块级作用域)
this对象
this对象:this所在的函数是当做哪个对象的方法调用的,this对象就指向该对象。this对象取决于函
数的执行环境,在javascript中,全局作用域中声明的变量和函数都是window对象的属性和方法,所以在全局执行环境中调用函数,this
对象始终指向window;如果函数以某个对象的方法被调用,this指向这个对象;如果以构造函数的形式被调用
this指向新构造的对象。以window对象为例:
var x = "hello";
function sayHello(){
alert("this.x");
}
sayHello(); //hello
window对象
window对象:window对象表示浏览器中打开的窗口,它表示一个浏览器的实例,它既是javascript
访问浏览器窗口的一个接口也是ECMAScript规定的Global对象。全局作用域中声明的变量和函数都是window
对象的属性和方法,定义在全局作用域中的变量和直接在window上定义的属性有所区别:全局变量不能通过
delete操作符删除。如果文档包含框架(frame 或 iframe 标签),浏览器会为 HTML 文档创建一个 window
对象,并为每个框架创建一个额外的 window 对象。
Ajax
Ajax:是指一种创建交互式网页应用的网页开发技术,通过在后台与服务器进行少量数据交换,
Ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
Ajax技术的核心是XMLHttpRequest对象(XHR),通过XMLHttpRequest对象Ajax在浏览器与 Web 服务器
之间使用异步数据传输(HTTP 请求),然后再通过DOM将新数据插入到页面中,这样就可使网页从服务器
请求少量的信息,而不是整个页面。但是Ajax通信与数据格式无关,请求来的数据不一定是XML数据
异步与同步的区别
异步与同步的区别:同步:当ajax发送请求后,在等待服务器端返回的过程中,会继续发出下一个
请求执行后面的代码
异步:当ajax发送请求后,在等待服务器端返回数据之后才执行下面的代码
对象和JSON
JSON:JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它基于ECMAScript的
一个子集,采用完全独立于语言的文本格式,这些特性使JSON成为理想的数据交换语言 易于人阅读和编写,
同时也易于机器解析和生成,传输相同的数据,JSON相比于XML更小巧。
JSON语法可以表示三种类型的值:简单值、对象和数组,JSON中的简单值表示字符串、数值、布尔值、和
null,但不支持undefined;花括号保存对象,例如
{
"name":"Mike",
"age": 23
} //对象的属性必须加双引号,属性的值也可以是复杂类型的值
方括号保存数组,JSON数组采用的就是JavaScript中的数组字面量形式,例如:
[ 25, "hello" , true ]
数组也可以保存复杂数据类型的值
JSON对象有两个方法:stringify()和parse(),这两个方法分别把javascript对象序列化为json字符串,把JSON
字符串解析为原生javascript值。
跨域处理
跨域处理:跨域是指从一个域名的网页去请求另一个域名的资源。比如从http://www.baidu.com/ 页面
去请求 http://www.google.com 的资源,只要协议、域名(包括主域名和子域名),端口有任何一个不同,就被
当作是跨域。 通过XHR实现Ajax通信,一般情况下XHR对象只能访问与包含它的页面位于同一个域中的资源,
但是合理的实现跨域请求也是相当有必要的
CORS:使用自定义的HTTP头部让浏览器与服务器进行沟通,例如:对于简单的get或post请求,浏览器发现这次
跨源AJAX请求是简单请求,就自动在头信息之中,添加一个Origin字段。
JSONP:JSONP是被包含在函数中调用的JSON,由两部分组成,回调函数和数据:回调函数就是当响应到来
时应该在页面中调用的函数,而数据就是传入回调函数中的JSON数据。JSONP是通过动态<script>元素来使用
的,使用时可以为src属性指定一个跨域URL
闭包
闭包:闭包是指有权访问另一个函数作用域中的变量的函数,一般嵌套的函数都会产生闭包 例如:
function a(){
var i = 0;
function b(){
alert(i ++);
}
return b;
}
var c = a();
c(); // 执行完var c=a()后,变量c实际上是指向了函数b,再执行c()后就会弹出一个窗口显示i的值(第一次为1)。
这段代码其实就创建了一个闭包,因为函数a外的变量c引用了函数a内的函数b,当函数a的内部函数b被函数a
外的一个变量引用的时候,就创建了一个闭包。所谓“闭包”,就是在构造函数体内定义另外的函数作为目标
对象的方法函数,而这个对象的方法函数反过来引用外层函数体中的临时变量。当函数a的内部函数b被函数a
外的一个变量引用的时候,就创建了一个闭包。
闭包的作用:在函数执行完毕后,javascript的垃圾回收机制不会回收该函数占用的资源,因为其内部函数的
执行需要依赖该函数的变量,即使其执行环境的作用域链被销毁,但它的活动对象仍保存在内存中。(局部
变量在函数执行完后会被释放内存)
在例子中如果我们第二次执行c(); 会弹出的值为2,
call()和apply()
call()和apply():ECMAScript中的函数是对象,因此函数也有属性和方法,每个函数都包括length
和prototype属性,length属性表示接受参数的个数,而prototype保存了函数所有的实例方法。
而call()和apply()是每个函数都包含的两个非继承而来的方法,这两个方法的用途都是在特定的作用域中调用函
数,实际上等于设置函数体内this对象的值。(用于传递参数)
apply()方法:接受两个参数,一个是在其中运行函数的作用域,另一个是参数数组(可以是Array的实例,也
可以是arguments对象)。
语法:apply(thisObj,[argArray])
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任
何参数。
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
call()方法:他与apply()方法的区别仅在与接收参数的方式不同。对于call()方法而言,第一个参数是this值没
有变化变化的是其余参数都直接传递个函数。换句话说就是在使用call()方法时,传递给函数的参数必须逐个
例举出来。
语法:call(thisObj,Object)
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为
由 thisObj 指定的新对象。 如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
DOM操作
DOM操作:DOM(文档对象模型)是针对HTML和XML文档的一个API(应用程序编程接口)。
DOM描绘了一个层次化的节点树,允许开发人员添加、移除和修改页面的某一部分。
createElement():创建一个新的元素节点;
createTextNode():创建一个包含着给定文本的新文本节点
appendChild():指定节点的最后一个子节点列表之后添加一个新的子节点;
insertBefore():将一个给定节点插入到一个给定元素节点的给定节点前面;
removeChild():从一个给定元素中删除一个节点;
replaceChild():把一个给定父元素里的一个节点替换为另一个节点;
cloneNode(): 创建调用这个方法的节点的一个完全相同的副本;
getElementById()/getElementsByTagName(): 获取特定的某个或某组元素的引用;
write()/writeln(): 将输入流写入到网页中;
getAttribute(): 取得元素的特性;
setAttribute():设置元素特性;
removeAttribute():彻底删除元素的特性;
normalize(): 将相邻文本节点合并成一个节点;
splitText() : 将一个文本节点分成两个文本节点;
createAttribute() : 为元素创建新的特性;
原型与原型链:
原型:我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象
而这个对象包含了特定实例共享的属性和方法,所以原型就是通过调用构造函数而创建的那个对象实例的原型
对象。使用原型对象可以让所有对象实例共享它所包含的属性和方法,例如:
function Person(){
}
Person.prototype.name = "Mike";
Person.prototype.age = 29;
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
person1.sayName(); //"Mike"
var person2 = new Person();
person1.sayName(); //"Mike"
新创建的函数的prototype属性指向函数的原型对象,所有原型对象会自动获得一个constructor属性,这个
属性包含一个指向prototype属性所在函数的指针,例:Person.prototype.constructor指向Person,
原型对象中除了包含constructor属性之外,还包含了后来添加的name age属性,Person构造函数的两个实例
正是通过原型对象共享到了它的属性和方法。
虽然可以通过对象实例访问保存在原型中的值,但却不能通过对象实例重写原型中的值
原型链:原型链在ECMAScript中主要是实现继承,其基本思想是让一个引用类型继承另一个引用
类型的属性和方法。每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包
含一个指向原型对象的内部指针,如果让一个原型对象等于另一个对象的实例,这时的原型对象将包含一个指
向另一个原型的指针,而另一个原型中也包含着一个指向另一个构造函数的指针,如此重复就构成了实例与原型
的链条,这就是原型链。
当访问一个实例属性时,首先在实例中搜索该属性,如果没有找到该属性就沿着原型链一步一步向上搜索
事件处理
事件处理:js与HTML的交互就是通过事件实现的,事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。
事件流:事件流描述的是从页面中接收事件的顺序
事件冒泡:由最具体的元素接收,然后逐级向上传播到更高级的节点,即事件沿DOM树向上传播,直到document
对象。
事件捕获:不大具体的节点应该更早接收到事件,相当于沿DOM节点树向下级传播直到事件的实际目标,在浏
览器中,是从window对象开始捕获事件的
事件处理程序:影响某个事件的函数就叫做事件处理程序(或事件侦听器)比如:click事件的事件处理程序就是
onclick
load:当页面完全加载后(包括所有图像、js文件、css文件等外部资源)就会触发window上面的load事件;
unload事件:这个事件在文档被完全卸载后触发,或者用户从一个页面切换到另一个页面触发;
resize事件:当浏览器窗口被调整到一个新的高度或宽度时触发;
scroll事件:scroll事件是在window对象上发生的,但它实际上表示的则是页面中相应元素的变化;
blur:在元素失去焦点时触发,这个事件不会冒泡,所有浏览器都支持它;
DOMFocusIn:在元素获得焦点时触发,与HTML事件focus等价,但它会冒泡,只有opera支持;
DOMFocusOut:元素失去焦点时触发,与HTML事件blur等价,但它会冒泡,只有opera支持;
focus:在元素获得焦点时触发,不会冒泡所有浏览器都支持它;
focusin:在元素获得焦点时触发,与HTML事件focus等价,但它会冒泡;
focusout:元素失去焦点时触发,这个事件是HTML事件blur的通用版本;
click:单击鼠标或者按下回车键时触发;
dblclick:双击鼠标时触发;
mousedown:用户按下了任意鼠标按钮时触发,不能通过键盘触发;
mouseenter:在鼠标光标从元素外部首次移动到元素范围之内时触发,事件不会冒泡,移动到后代元素上也
不会触发;
mouseleave:在位于元素上方的鼠标光标移动到元素范围之外时触发,事件不会冒泡,移动到后代元素上也
不会触发;
mousemove:当鼠标指针在元素内部移动是重复地触发;
mouseout:在鼠标指针位于一个元素上方,然后用户将其移入到另一个元素时触发;
mouseover:在鼠标指针位于一个元素外部,然后用户将其首次移入另一个元素边界之内时触发;
mouseuop:在用户释放鼠标时触发;
keydown:当用户按下键盘上的任意键时触发,如果按住不放会重复触发此事件;
keypress:当用户按下键盘上的字符键时触发,如果按住不放会重复触发此事件(Esc也会触发);
keyup:当用户释放键盘上的键时触发;
数组方法
数组方法:数组也是变量,但是数组可以存储多个值,即是存储数据的有序列表,但ECMAScript
中数组的每一项可以保存任何数据类型的值。
数组对象的属性:
length:设置或返回数组中元素的数目
constructor:返回对创建此对象的数组函数的引用
prototype:向对象添加属性和方法
数组方法:
concat():用于连接两个或多个数组,该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本;
var a = [1,2,3];
document.write(a.concat(4,5)); //1,2,3,4,5
join():用于把数组中的所有元素放入一个字符串,元素是通过指定的分隔符进行分隔的。
var a = [1,2,3];
document.write(a.join("|")); //1|2|3
pop() :用于删除并返回数组的最后一个元素
var a = [1,2,3];
document.write(a.pop()); // 3
push() :向数组的末尾添加一个或多个元素,并返回新的长度
var a = [1,2,3];
document.write(a.push("4","5")); // 5
reverse() :颠倒数组中元素的顺序, 改变原来的数组,而不会创建新的数组
var a = [1,2,3];
document.write(a.reverse()); //3,2,1
shift() :把数组的第一个元素从其中删除,并返回第一个元素的值
slice() : 从已有的数组中返回选定的元素 , arrayObject.slice(start,end)该方法并不会修改数组,而是返回一个子数组
var arr = new Array(6)
arr[0] = "George"
arr[1] = "John"
arr[2] = "Thomas"
arr[3] = "James"
arr[4] = "Adrew"
arr[5] = "Martin"
document.write(arr.slice(2,4) ) //Thomas,James
document.write(arr) //George,John,Thomas,James,Adrew,Martin
sort() :对数组的元素进行排序 , 按照字符编码的顺序进行排序
splice() : 向/从数组中添加/删除元素,然后返回被删除的元素
var arr = new Array(6)
arr[0] = "George"
arr[1] = "John"
arr[2] = "Thomas"
arr[3] = "James"
arr[4] = "Adrew"
arr[5] = "Martin"
arr.splice(2,0,"William")
document.write(arr) //George,John,William,Thomas,James,Adrew,Martin
toSource() :表示对象的源代码,该原始值由 Array 对象派生的所有对象继承
toString() :把数组转换为字符串,并返回结果
toLocaleString():把数组转换为本地字符串
unshift() :向数组的开头添加一个或更多元素,并返回新的长度
var arr = new Array()
arr[0] = "George"
arr[1] = "John"
arr[2] = "Thomas"
document.write(arr.unshift("William") ) //4
document.write(arr) //William,George,John,Thomas
valueOf():返回 Array 对象的原始值,该原始值由 Array 对象派生的所有对象继承
正则表达式
正则表达式:总体来说,正则表达式最大的作用就是用来匹配字符。javascript通过RegExp类型来
支持正则表达式,使用Perl语法创建一个正则表达式: var re = /pattern/flags; 其中模式(pattern)部分是要
匹配的字符,标志(flags)用以表明正则表达式的行为,g、i、m,分别代表全局匹配、忽略大小写、多行模
式,三种属性可以自由组合共存。
模式中使用的所有元字符都必须用转义符"\"转义,包括:( [ { \ ^ $ | ) ? * + .
另一种创建正则表达式的方法是使用RegExp构造函数,它接收两个参数:要匹配的字符串模式和一个可选的
标志字符串,例如: var re = new RegExp("bat","g"),这种方法下的元字符需要用"//"双重转义符转义。
使用正则表达式字面量和RegExp构造函数创建的正则表达式不一样,正则表达式字面量始终会共享同一个
RegExp实例,而使用构造函数创建的每一个新RegExp实例都是一个新实例
RegExp实例属性
global :是当前表达式模式首次匹配内容的开始位置,从0开始计数。其初始值为-1,每次成功匹配时,index属性都会随之改变。
ignoreCase :返回创建RegExp对象实例时指定的ignoreCase标志(i)的状态。如果创建RegExp对象实例时设置了i标志,该属性返回True,否则返回False,默认值为False。
lastIndex:是当前表达式模式首次匹配内容中最后一个字符的下一个位置,从0开始计数,常被作为继续搜索时的起始位置,初始值为-1, 表示从起始位置开始搜索,每次成功匹配时,lastIndex属性值都会随之改变。(只有使用exec()或test()方法才会填入,否则为0)
multiLine:返回创建RegExp对象实例时指定的multiLine标志(m)的状态。如果创建RegExp对象实例时设置了m标志,该属性返回True,否则返回False,默认值为False。
source:返回创建RegExp对象实例时指定的表达式文本字符串
search()方法: 用来找出原字符串中某个子字符串首次出现的index,没有则返回-1
"abchello".search(/hello/); // 3
replace(): 方法用来替换字符串中的子串 "abchello".replace(/hello/,"hi"); // "abchi"
test()方法: 用来测试字符串中是否含有子字符串,返回布尔值
/hello/.test("abchello"); // true
match(): 用来捕获字符串中的子字符串到一个数组中。默认情况下只捕获一个结果到数组中,正则表达式
有”全局捕获“的属性时(定义正则表达式的时候添加参数g),会捕获所有结果到数组中
"abchelloasdasdhelloasd".match(/hello/g); //["hello","hello"]
exec(): 这个方法也是从字符串中捕获满足条件的字符串到数组中, exec()方法一次只能捕获第一个匹配的
子字符串到数组中,无论正则表达式是否有全局属性
.:[^\n\r] //除了换行和回车之外的任意字符
\d:[0-9] //数字字符
\D:[^0-9] //非数字字符
\s:[ \t\n\x0B\f\r] //空白字符
\S:[^ \t\n\x0B\f\r] //非空白字符
\w:[a-zA-Z_0-9] //单词字符(所有的字母)
\W:[^a-zA-Z_0-9] //非单词字符
?:出现零次或一次
*:出现零次或多次(任意次)
+:出现一次或多次(至道一次)
{n}:对应零次或者n次
{n,m}:至少出现n次但不超过m次
{n,}:至少出现n次
^:开头
$:结尾
\b:单词边界,指[a-zA-Z_0-9]之外的字符
\B:非单词边界