javascript核心
函数
- 声明式函数(命名方式):
function test(){alert("hello")};
代码先于函数执行代码被解析器解析 - 引用式函数(匿名方式):
var test = function(){alert("hello")};
函数运行中进行动态解析的
对象
- 内置属性和方法
hasOwnProperty():从原型继承来的属性不会被识别
isPrototypeOf():检查对象是否是指定对象的原型
propertyIsEmuerable():检查对象是否拥有指定属性,且此属性可被for/in循环枚举
toLocaleString()
toString():返回对象的字符串
valueOf() - 对象的销毁和存储单元的回收
CollectGarbage():IE调用这个函数可以立即回收无用的对象
实际上不用调用任何函数浏览器也会按照自己的规律执行存储单元的回收 - 内置对象
Math对象
Date对象
Error对象
Function对象
Arguments对象
String对象
Number对象
Boolean对象
集合
- 数组:数组常量赋值要比Array()构造数组的速度更快
join()、reverse()、sort()、concat()、slice(startPos,endPos)、splice(pos,count,insertValue)、toString()、roLocaleString()
eg:下面代码结果为1@30@40@50,60@70@3
,数组作为插入元素时不会展开,与concat不同
var arr=[1,2,3];
arr.splice(1,1,30,40,[50,60],70);
alert(arr.join("@"));
- 哈希表:key-value(码值对)
in:检查关键码是否在集合中,delete:删除指定属性,eg:delete(hashTable["a"]
或delete hashTable.a
字符串
- String对象的方法
charAt():返回指定位置字符、charCodeAt():返回指定位置Unicode编码、indexOf()、lastIndexOf()、substring()、slice()、split()、match()、search()、replace()、concat()
正则表达式
一般和字符串方法split()、match()、search()、replace()结合使用
var reg1 = new RegExp("js");
var reg2 = /([\d])|([a-z])|([A-Z])/g;
修饰符 | 描述 |
---|---|
i | 执行对大小写不敏感的匹配 |
g | 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止) |
m | 执行多行匹配 |
参考链接:https://segmentfault.com/a/1190000008578123
- 方法
test():遍历字符串,有匹配,返回true、exec():搜索符合规则的内容,并返回数组,无则返回null
浏览器与DOM(JavaScript客户端环境)
浏览器对象
- Window对象
window对象生命周期为:浏览器进程从开始到结束的整个过程
如下代码列举window对象的属性和方法
for (p in window) document.write(p+"<br/>")
- Document对象:浏览器窗口文档内容的代表
定义了4个方法:open()、close()、write()、writeln()
基本属性:title、domain、referrer、location、URL、lastModified、frames、parent,status(状态栏)
frames:Frame对象的集合,多框架应用,可递归嵌套,window.frames[0].frames[1]
self(当前窗口,自身)和top(顶级窗口):if(self != top){top.location = self.location}
Document子对象接口
images[]:代表文档中的图片元素
links[]:代表文档中的一个链接
cookie:非集合类型,提供有限的数据存储能力
applets[]:代表文档中的java小程序
anchors[]:代表文档中的锚
forms[]:代表文档中的表单元素,document.forms.length,常用属性elements[]、action、encoding、method、target
eg:
<a name="a1">1</a>
<a name="a2">2</a>
<a>3</a>
<script>
for(var i=0;i<document.anchors.length;i++)
{
document.write(document.anchors[i].name);
}
</script>
<form onsubmit="show(this);return false;">
姓名:<input name="name" /><br/>
密码:<input name="password" type="password" /><br/>
<input type="submit" /><input type="reset" />
</from>
<script>
function show(form)
{
var str = "";
for(var i=0;i<form.elements.length;i++)
{
str += form.elements[i].name+"="form.elements[i].value+"<br/>";
}
document.write(str);
}
</script>
- Navigator对象:浏览器总体信息的代表
- Screen对象:提示显示器分辨率和可用颜色数信息
- location对象:当前窗口中显示文档的URL的代表
- History对象
文档对象模型DOM
DOM分类:HTML DOM和XML DOM。HTML DOM 是对 DOM Core 的扩展,添加了专门针对 HTML 文档的特定对象和方法,它与现有的文档对象模型一致。
HTML DOM API 的主要作用概况如下:
定义文档的结构
访问文档的方式
操作文档的方式
- 获取节点
方法 | 语法 | 描述 |
---|---|---|
document.getElementById() | document.getElementById(元素ID); | 通过元素ID获取节点 |
document.getElementsByName() | document.getElementsByName(元素name属性) | 通过元素的name属性获取节点 |
document.getElementsByTagName() | document.getElementsByTagName(元素标签) | 通过元素名获取节点 |
- 节点指针
名称 | 语法 | 描述 |
---|---|---|
firstChild | 父节点.firstChild | 获取元素的首个子节点 |
lastChild | 父节点.lastChild | 获取元素的最后一个子节点 |
childNodes | 父节点.childNodes | 获取元素子节点列表 |
previousSibling | 兄弟节点.previousSibling | 获取已知节点的上一个节点 |
nextSibling | 兄弟节点.nextSibling | 获取已知节点的下一个节点 |
parentNode | 子节点.parentNode | 获取已知节点的父节点 |
- 操作节点、属性、文本
方法 | 语法 | 描述 |
---|---|---|
createElement() | document.createElement(元素标签) | 创建元素节点 |
createAttribute() | document.createAttribute(元素属性) | 创建属性节点 |
createTextNode() | document.createTextNode(文本内容) | 创建文本节点 |
appendChild() | appendChild(添加的新节点) | 向节点的子节点列表的末尾添加新的子节点 |
inaertBefore() | insertBefore(要添加的新节点,已知节点) | 在已知的节点前插入新的节点 |
replaceChild() | replaceChild(要插入的新元素,将被替换的老元素) | 将某个子节点替换为另一个 |
cloneNode() | 需要复制的节点.cloneNode(true/false) | 创建指定节点副本,true复制当前节点及其子节点 |
removeChild() | removeChild(要删除的节点) | 删除指定节点 |
replaceChild() | replaceChild(要插入的新元素,将被替换的老元素) | 将某个子节点替换为另一个 |
getAttribute() | 元素节点.getAttribute(元素属性名) | 获取元素节点中指定属性的属性值 |
setAttribute() | 元素节点.setAttribute(属性名,属性值) | 创建或改变元素节点的属性 |
removeAttribute() | 元素节点.removeAttribute(属性名) | 删除元素中指定属性 |
insertData() | insertData(offset,String) | 从offset指定的位置插入string |
appendData() | appendData(string) | 将string插入到文本节点的末尾处 |
deleteData() | deleteData(offset,count) | 从offset起删除count个字符 |
replaceData() | replaceData(off,count,string) | 从off将cuont个字符用string替换 |
splitData() | splitData(offset) | 从offset起将文本节点分成两个节点 |
substring() | substring(offset,count) | 返回由offset起的count个节点 |
事件处理
- 标准事件类型
参考链接:http://javascript.ruanyifeng.com/dom/event-type.html - 事件绑定
-在JavaScript中,有三种常用的绑定事件的方法:
1.在DOM元素中直接绑定;
2.在JavaScript代码中绑定;
3.绑定事件监听函数。绑定事件的另一种方法是用 addEventListener() 或 attachEvent() 来绑定事件监听函数,即如下的事件监听。
<input type="button" value="click me" onclick="hello()">
<script>
function hello(){
alert("hello world!");
}
</script>
<input type="button" value="click me" id="btn">
<script>
document.getElementById("btn").onclick = function(){
alert("hello world!");
}
</script>
- 事件监听
其优点是可以绑定多个事件。常规的事件绑定只执行最后绑定的事件。
语法:element.addEventListener(event, function, useCapture)
Event对象在DOM level-2中是被作为事件接收函数(闭包)的参数传递的,在IE中则为Window对象属性。
关于事件监听,W3C规范中定义了3个事件阶段,依次是捕获阶段、目标阶段、冒泡阶段。
1、目标:最具体的元素
2、捕获:事件由页面元素接收,逐级向下,到最具体的元素
3、冒泡:跟捕获相反,由最具体的元素接收,逐级向上,到页面元素
IE的事件流是采用捕获事件,而DOM的事件流是先捕获后冒泡。
event : (必需)事件名,支持所有 DOM事件 。
function:(必需)指定要事件触发时执行的函数。
useCapture:(可选)指定事件是否在捕获或冒泡阶段执行。true,捕获。false,冒泡。默认false。
借用W3C文档中的图说明三个事件阶段过程,参考链接:https://www.w3.org/TR/DOM-Level-3-Events/#event-type-blur
文档中指出select、click、mousedown、mousemove、mouseout、mouseover、mouseup、keydown、keyup、keypress等都具有冒泡特性,也有一些如focus、blur等不具有冒泡特性。
取消冒泡和事件默认行为:
function stopBubble(e){
//如果传入事件对象且支持W3C的stopPropagation的用法
if(e && e.stopPropagation){
//即为非IE浏览器
e.stopPropagation();
}else{
//IE方式取消事件冒泡
window.event.cancelBubble=true;
}
function stopDefault( e ) {
//阻止默认浏览器动作(W3C)
if ( e && e.preventDefault ) {
e.preventDefault();
}else{
//IE中阻止函数器默认动作的方式
window.event.returnValue = false;
}
return false;
}
事件监听例子,两个事件都会执行。
<input type="button" value="click me" id="btn">
<script>
var btn = document.getElementById("btn");
btn.addEventListener("click",hello1);
btn.addEventListener("click",hello2);
//btn.removeEventListener("click",hello2); 移除事件
function hello1(){
alert("hello 1");
}
function hello2(){
alert("hello 2");
}
</script>
- 事件委托
事件委托就是利用冒泡的原理,把事件加到父元素或祖先元素上,触发执行效果。
提高JavaScript性能。事件委托可以显著的提高事件的处理速度,减少内存的占用。
动态的添加DOM元素,不需要因为元素的改动而修改事件绑定。
适合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。
<div id="box">
<input type="button" id="add" value="添加" />
<input type="button" id="remove" value="删除" />
<input type="button" id="move" value="移动" />
<input type="button" id="select" value="选择" />
</div>
<script>
window.onload = function(){
var oBox = document.getElementById("box");
oBox.onclick = function (event) {
var event = event || window.event;
//此句消除了IE与Mozilla之间在事件参数方面的部分差异
var target = event.target || event.srcElement;
//IE 中srcElement代表事件触发者,而Mozilla中相应属性为target
if(target.nodeName.toLocaleLowerCase() == 'input'){
switch(target.id){
case 'add' :
alert('添加');
break;
case 'remove' :
alert('删除');
break;
case 'move' :
alert('移动');
break;
case 'select' :
alert('选择');
break;
}
}
}
}
</scritp>
数据存储
方法 | 描述 |
---|---|
cookie | (1)保存在浏览器端,大小不超过4K,且需要自己封装。(2)如果不在浏览器中设置过期时间,cookie被保存在内存中,生命周期随浏览器的关闭而结束,这种cookie简称会话cookie。如果在浏览器中设置了cookie的过期时间,cookie被保存在硬盘中,关闭浏览器后,cookie数据仍然存在,直到过期时间结束才消失。(3)数据始终在同源的http请求中携带,同源窗口共享,即cookie在浏览器和服务器之间来回传递。(4)只能保存字符串类型,以文本的方式。 |
localStorage | (1)至少5M,不会自动把数据发给服务器,仅在本地保存。(2)没有时间限制的数据存。(3)在所有同源窗口中都是共享的。(4)存储字符串类型,对于复杂的对象可以使用ECMAScript提供的JSON对象的stringify和parse来处理。 |
sessionStorage | (1)至少5M,不会自动把数据发给服务器,仅在本地保存。(2)针对一个 session 的数据存储,当用户关闭浏览器窗口后,数据会被删除。(3)不在不同的浏览器窗口中共享。(4))存储字符串类型,对于复杂的对象可以使用ECMAScript提供的JSON对象的stringify和parse来处理 |
session | (1)大小没有限制。(2)当服务器收到请求需要创建session对象时,首先会检查客户端请求中是否包含sessionid。如果有sessionid,服务器将根据该id返回对应session对象。如果客户端请求中没有sessionid,服务器会创建新的session对象,并把sessionid在本次响应中返回给客户端。 |
注:
1. 通常使用cookie方式存储sessionid到客户端,在交互中浏览器按照规则将sessionid发送给服务器。如果用户禁用cookie,则要使用URL重写,可以通过response.encodeURL(url) 进行实现;API对encodeURL的结束为,当浏览器支持Cookie时,url不做任何处理;当浏览器不支持Cookie的时候,将会重写URL将SessionID拼接到访问地址后。
2. Web Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。Web Storage 的 api 接口使用更方便。参考链接:https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API,其常用方法如下:
保存数据:localStorage.setItem(key,value);
读取数据:localStorage.getItem(key);
删除单个数据:localStorage.removeItem(key);
删除所有数据:localStorage.clear();
得到某个索引的key:localStorage.key(index);
用法实例如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<head>
<script>
function setCookie(cname,cvalue,exdays){
var d = new Date();
d.setTime(d.getTime()+(exdays*24*60*60*1000));
var expires = "expires="+d.toGMTString();
document.cookie = cname+"="+cvalue+"; "+expires;
}
function getCookie(cname){
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name)==0) { return c.substring(name.length,c.length); }
}
return "";
}
function checkCookie(){
var user=getCookie("username");
if (user!=""){
alert("欢迎 " + user + " 再次访问");
}
else {
user = prompt("请输入你的名字:","");
if (user!="" && user!=null){
setCookie("username",user,30);
}
}
}
</script>
</head>
<body onload="checkCookie()"></body>
</html>
数据交互
同步和异步
- 概念
Javascript语言的执行环境是”单线程”(single thread),这种模式好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。
Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。
同步:程序的执行顺序与任务的排列顺序是一致的
异步:每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的
具体参考链接:http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html - 异步执行方式
1.超时设定和时间间隔
setTimeout()、setInterval()
<script type="text/javascript">
function test(){
for(var i=0;i<5;i++){
(function(i){
setTimeout(function(){alert(i)}.100);
})(i);
}
}
</script>
<div id="clock"></div>
<script type="text/javascript">
setInterval("document.getElementById("clock").innerText = new Date();",1000);
</script>
2.利用script属性来实现js异步
defer:当页面加载完毕以后才去执行这段代码。async:异步执行script代码
<script type="text/javascript" src="test.js" defer></script>
3.AJAX实现异步提交
$.ajax({
url: "", //服务器路径
data: { }, //传递的参数,可为空,可多个
type: "post", //传递参数的方式,可POST可GET,一般用POST
dataType: "json", //数据传递的格式,有Json和xml两种
success: function (data) { //成功返回数据执行这里,排第2
},
beforeSend: function () { //一触发ajax就执行,无任何延迟,排第1
},
complete: function () { //所有的方法都执行完毕后再来执行这里,排最后(不管成功失败都会执行)
},
error: function () { //服务器路径错误,或是服务器内部错误,走这里报错,此位置与success只会走一个
}
});
4.回调函数
回调函数定义:函数A作为参数(函数引用)传递到另一个函数B中,并且这个函数B执行函数A。我们就说函数A叫做回调函数。如果没有名称(函数表达式),就叫做匿名回调函数。
因此callback 不一定用于异步,一般同步(阻塞)的场景下也经常用到回调,比如要求执行某些操作后执行回调函数。
回调函数执行:一般在同步情境下是最后执行的,而在异步情境下有可能不执行,因为事件没有被触发或者条件不满足。
回调函数使用场合:动态加载js文件后执行回调,加载iframe后执行回调,ajax操作回调等。
输出结果:
我是主函数
我是回调函数
定义主函数的时候,代码先去执行callback()回调函数,但输出结果却是后输出回调函数的内容。这就说明了主函数不用等待回调函数执行完,可以接着执行自己的代码。所以一般回调函数都用在耗时操作上面。比如ajax请求,比如处理文件等。
//定义主函数,回调函数作为参数
function A(callback) {
callback();
console.log('我是主函数');
}
//定义回调函数
function B(){
setTimeout("console.log('我是回调函数')", 3000);//模仿耗时操作
}
//调用主函数,将函数B传进去
A(B);
5.事件监听
事件驱动模式,任务的执行不取决代码的顺序,而取决于某一个事件是否发生。
监听函数有:on,bind,listen,addEventListener,observe
function f1(){
settimeout(function(){
//f1的任务代码
f1.trigger('done');
},1000);
}
f1.on('done',f2);
6.发布/订阅(观察者模式)
它定义了一种一对多的关系,让多个观察者同时对监听某一个主题对象,这一个主题对象的状态变化就会通知多有的观察者对象,使得他们能够自动更新自己。
优点:支持简单的广播通信,自动通知所有已经订阅过的对象。页面载入后,目标对象很容易与观察者存在一种动态关联,增加灵活性。时间上解耦,对象间解耦。
缺点:创建这个函数同样需要内存,过度使用会导致难以跟踪维护。
7.Promise对象
promise对象是commonJS工作组提出的一种规范,一种模式,目的是为了异步编程提供统一接口。
promise是一种模式,promise可以帮忙管理异步方式返回的代码。
promise状态变化过程:等待(pending)=>解决(resolved)或 等待(pending)=>拒绝(rejected)
promise会一直处于等待状态,直到它所包装的异步调用返回/超时/结束。
具体用法参考链接:
http://es6.ruanyifeng.com/#docs/promise
https://www.jianshu.com/p/c98eb98bd00c
Ajax简介
无刷新解决方案
- 讨厌的页面刷新
<script type="text/javascript">
setTimeout("document.forms[0].submit();",2000);
//每隔2秒自动向服务器发起请求,提交表单页面总是会刷新
</script>
- XmlHttp实现无刷新(原生Ajax技术)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>XmlHttp的使用</title>
</head>
<script type="text/javascript">
function submit(url){
if (window.XMLHttpRequest){// code for all new browsers
xmlHttp=new XMLHttpRequest();
}else if (window.ActiveXObject){// code for IE5 and IE6
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttp.open("POST",url,true);//get方式同info.php交互,true表示异步处理
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlHttp.onreadystatechange=state_Change;//注册回调函数时只需要函数名不要加括号
var fd = new FormData;
fd.append("messages",document.getElementById("messages").value);
xmlHttp.send(fd);
//messages = document.getElementById("messages").value;
//xmlHttp.open("GET",url+"?messages="+messages,true);
//xmlHttp.send(null);
}
function state_Change(){
if (xmlHttp.readyState==4){// 4 = "loaded"
if (xmlHttp.status==200){// 200 = OK
// ...our code here...
var resText = xmlHttp.responseText;
document.getElementById("showMsg").innerHTML = resText;//新返回的文本写入聊天窗口
}
}
}
url = 'info.php';
setInterval("submit(url)",1000);
</script>
<body>
<div id="showMsg"></div>
<form id="info">
<input name="messages" id="messages" type="text" style="width: 220px;">
<input type="submit" name="submit" id="submit" onclick="submit("info.php");">
</form>
</body>
</html>
- 异步请求代理ajaxProxy(封装了XML HTTP)
参考链接:http://www.charlestech.info/2015/05/27/ajax-proxy/?utm_source=tuicool&utm_medium=referral
github上开源:https://github.com/charleschaochen/ajaxProxy - jQuery ajax() 方法
jQuery 库拥有完整的 Ajax 兼容套件。其中的函数和方法允许我们在不刷新浏览器的情况下从服务器加载数据。
参考链接:http://www.w3school.com.cn/jquery/ajax_ajax.asp ; http://api.jquery.com/jquery.ajax/ - prototype.js 的 Ajax.updater
new Ajax.Updater(container, url[, options])
:执行一个 AJAX 请求,并将响应内容更新到指定容器。
参考链接:http://www.cnblogs.com/beyondGodLike/archive/2009/08/04/1538543.html