一,对象

var user = new Object; -> 方式一
user.username = "wjx";
user["age"]=20;

var user = {username:"wjx",age:20}; -> 方式二

function User(username,age){ -> 方式三
  this.username = username;
  this.age = age;
  
  function setName(username){
    this.username = username;
  }
}
var user = new User("wjx",20); -> 通过构造器生成对象
user.setName("wjx"); -> 调用对象内部方法

for (var x in user){ -> 遍历对象属性
document.write(user[x] + "<br />")
}

var fun = function(){} -> 使用变量存储函数
onclick = "fun"; -> 调用对象等同调用函数

Math.ceil(number); -> 向上取整
Math.round(number); -> 四舍五入
Math.floor(number); -> 向下取整

二,数组

var names = new Array(); -> 方式一
names[0] = "wjx";
names[1] = "xjw";
var names = new Array("wjx","xjw"); -> 方式二
var names = ["wjx","xjw"]; -> 方式三

for (var x in names){ -> 遍历数组对象属性
document.write(names[x] + "<br />");
}

for(var x of names){ -> 遍历数组对象本身
document.write(names[x] + "<br />");
}

names.foreach(function(value,index,array){
  value = names[index]; -> 等价
  array = names; -> 等价
});

$.each(names,function(index,value){ -> JQuery  
});

names.map(function(value,index,array){
  value = names[index]; -> 等价
  array = names; -> 等价
  return index; -> 可返回值
});

$.map(names,function(value,index){ -> JQuery
    return index;
});

array.map(double); -> 返回值是原数组两倍的新数组
function double(value){return value*2};

array.concat(array); -> 合并数组
array.slice(start,end); -> 通过下标取出数组元素
array.splice(index,num); -> 从某个下标起删除任意个数组元素
array.splice(index,num,"a",...,"z"); -> 通过上述操作后再添加数组元素
array.join("."); -> 把数组元素以.拼接成字符串
array.sort(); -> 数组排序,从小到大,A>Z|1>2
array.reverse(); -> 数组元素颠倒排序
array.indexOf(index); -> 通过下标取出数组元素
array.indexOf(object); -> 获取元素在数组里的下标,找不到-1
array.item(index); -> 通过下标取出数组元素

array.unshift(~,...,~); -> 数组头部添加任意元素
array.push(~,...,~); -> 数组尾部添加任意元素
array.shift(); -> 数组头部删除一个元素并返回
array.pop(); -> 数组尾部删除一个元素并返回

var object = jQuery.parseJSON(json); -> JSON字符串转对象
var json = JSON.stringify(object); -> 对象转JSON字符串

var fi = string.indexOf("."); -> 获取字符串中第一次出现的下标
var li = string.lastIndexOf("."); -> 获取字符串中最后一次出现的下标

三,函数

function name(){} -> 方式一
var name = function(){} -> 方式二
name(); -> 使用方式一样

function a(){
  function b(){}
  return b; -> 返回类型是函数
}
a()(); -> 执行内部函数b

function a(){
  return {'name':'wjx'}; -> 返回类型是对象
}
a().name; -> 获取对象的属性值

(function(a,b){ -> 创建并立即执行函数
  $number = a*b;
})(2,5);

四,DOM

节点类型:nodeType
元素(element):1,属性(attr):2,文本(text):3,注释(comments):8,文档(document):9
node.parentNode; -> 返回节点的父节点(document是节点)
node.parentElement; -> 返回节点的父元素节点(默认两者获取的结果一样)
node.childNodes; -> 返回节点的所有子节点(空格换行符也是节点)
node.children; -> 返回节点的所有子元素节点
node.previousSibling; -> 返回节点的前一个同级节点
node.previousElementSibling; -> 返回节点的前一个同级元素节点
node.nextSibling; -> 返回节点的后一个同级节点
node.nextElementSibling; -> 返回节点的后一个同级元素节点
node.firstChild; -> 返回节点的第一个子节点
node.firstElementChild; -> 返回节点的第一个子元素节点
node.lastChild; -> 返回节点的最后一个子节点
node.lastElementChild; -> 返回节点的最后一个子元素节点

添加元素节点
var p = document.createElement("p"); -> 创建元素
var node =  document.createTextNode("节点内容"); -> 元素内容
p.appendChild(node); -> p元素创建完成
parent.appendChild(p); -> 把p元素加入父元素

p.innerHtml = "html"; -> 替换p元素的内容
p.style.color = red; -> 设置p元素的样式
var color = p.currentStyle.color|p.currentStyle[color]; -> 获取p元素的样式 
var obj = window.getComputedStyle(p,null); -> 获取p元素封装样式的对象
var color = obj.color|obj[color]; -> 获取样式对象的属性值

删除元素节点
var child = document.getElementById(cid);
var parent = document.getElementById(pid);
parent.removeChild(child); -> 方式一
child.parentNode.removeChild(child); -> 方式二

插入元素节点
var insert = document.createElement("p");
insert.innerHtml = "节点内容";
var before = document.getElementById("before"); 
parent.insertBefore(insert,before); -> 在before元素前插入insert

替换元素节点
var replace = document.createElement("p"); -> 替换的元素
var child = document.getElementById(cid); -> 被替换的元素
parent.replaceChild(replace,child);

查找元素的方式
var element = document.getElementById("id"); -> 通过元素id查找
var array = document.getElementsByTagName("p"); -> 通过元素标签名查找
var array = document.getElementsByName("name"); -> 通过元素属性name查找
var array = document.getElementsByClassName("class"); -> 通过类名查找
var element = document.querySelector("#id .class div"); -> 通过元素选择器查找
var array = document.querySelectorAll("#id .class div"); -> 通过元素选择器查找

设置元素属性
element.setAttribute("id","wjx"); -> 通过键值对方式设置
var id = document.createAttribute('id'); -> 创建属性节点
id.nodeValue="wjx"; -> 设置属性节点的值
element.setAttributeNode(id); -> 设置属性节点入元素

获取元素属性
var id = element.getAttribute("id"); -> 获取元素属性的值
var node = element.getAttributeNode("id"); -> 获取元素属性对象
var value = node.value; -> 获取元素属性对象的值

移除元素属性
element.removeAttribute("id"); -> 移除元素的属性
element.removeAttributeNode(node); -> 移除元素属性节点

var comment = document.createComment(); -> 创建注释节点

五,事件监听

标签内监听的事件名称带ON
JavaScript或jQuery对象监听的事件名称不带ON
onsubmit = "onsubmit()"; -> 表单提交
onreset = "onreset()"; -> 表单重置按钮被点击
onload = "onload()"; -> 用户进入页面
onunload = "onunload()"; -> 用户离开页面
onfocus = "onfocus()"; -> 元素获得焦点
onblur = "onblur()"; -> 元素失去焦点
onchange = "onchange()"; -> 输入框内容发生变化
onmouseover = "onmouseover()"; -> 鼠标进入元素
onmouseout = "onmouseout()"; -> 鼠标离开元素
onmousemove = "onmousemove()"; -> 鼠标移动
onmousedown = "onmousedown()"; -> 鼠标按下
onmouseup = "onmouseup()"; -> 鼠标提起
onclick = "onclick()"; -> 元素的单击事件
ondbclick = "ondbclick()"; -> 元素的双击事件
onabort = "onabort()"; -> 图像加载被中断
onerror = "onerror()"; -> 文档或图像加载发生错误
onselect = "onselect()"; -> 文本被选中
onresize = "onresize()"; -> 窗口被重新调整大小
onkeydown = "onkeydown()"; -> 某个键盘按键被按下
onkeypress = "onkeypress()"; -> 某个键盘按键被按下及松开
onkeyup = "onkeyup()"; -> 某个键盘按键被松开
on_* = "return true|false"; -> 任何事件,都可以通过返回值决定是否触发该事件

button.click(); -> 主动触发一次按钮的点击
button.click(function(){}); -> 监听事件回调

设置监听事件
<body onload = "onload();"></body> -> 标签内部
document.body = onload(); -> 对象属性
button.addEventListener("click",function(){},false); -> JavaScript
button.attachEvent("onclick",function(){}); -> JavaScript
$ul.on("click","li",function(){}); -> JQuery
button.removeEventListener("click",function(){}); -> 移除监听事件

事件冒泡:事件向上传导,后代元素的事件被触发时,其祖先元素的相同事件也会被触发
li.onclick = function(){点击li,先触发li的点击事件,继而触发ul的点击事件};
ul.onclick = function(event){
  event = event || window.event;
  event.cancelBubble = true; -> 取消事件冒泡
  event.stopPropagation(); -> 停止事件冒泡
  event.preventDefault(); -> 取消事件的默认行为
};

事件委派:将事件绑定到共同的祖先元素,减少事件绑定的次数
委派原理:事件的向上传递,其祖先元素可以捕获到后代元素的事件
使用场景:通过JS动态生成的元素无法静态设置监听事件
ul.onclick = function(){ul及li都能监听到点击事件};

事件传播的三个阶段
1、捕获阶段,从最外层的祖先元素,向目标元素进行事件的捕获,此时不会触发事件
2、目标阶段,事件捕获到目标元素,在目标元素上触发事件
3、冒泡阶段,事件从目标元素向其祖先元素传递,依次触发祖先元素上的事件

isNaN(num); -> 判断num是否为数字,返回boolean值
parseInt(string); -> 从字符串中抽出数字
parseFloat(string); -> 从字符串中抽出浮点数
object.toString(); -> 强转字符串

+ new Date(); -> 巧用+的小技巧,将时间由日期类型转换成长整型
callback || callback(); -> 巧用||的小技巧,当callback为true,不执行callback()
callback && callback(); -> 巧用&&的小技巧,当callback为false,不执行callback()
$(".class") with $(".class "); -> 获取的元素对象是不同的
alert("警告框")|confirm("确认框")|prompt("提示框","默认值");

<a href="javascript:;"/>; -> 执行空脚本
<a href="javascript:alert('JavaScript');"/>; -> 执行JS函数
onclick = "function1();function2();"; -> 同时触发多个函数 

六,正则

创建方式
var reg = new RegEx("正则表达式","匹配模式");
var reg = /正则表达式/匹配模式;

var boolean = reg.test(string); -> 检测字符串是否符合正则表达式规则
var array = string.split(reg); -> 将字符串按正则表达式规则切割
var index = string.search(reg); -> 返回符合规则的字符坐标,不符合返回-1
var content = string.match(reg); -> 返回符合条件的内容
var string = string.replace(reg,"replace"); -> 替换符合正则表达式的字符串
typeof reg; -> 检查对象的数据类型
typeof reg == 'undefined'; -> 是否未定义

匹配模式
g(global):全文检索
i(ignore case):忽略大小写
m(multiple lines):多行检索

预定义符号
\n 换行符,\r 回车符,\t 水平制表,\v 垂直制表
\o 空字符,\f 换页符,\b 单词边界,\B 非单词边界
\d 数字符号[0-9],\D 非数字符号[^0-9]
/s 空白符[\t\n\x0B\f\r],/S 非空白符[^\t\n\x0B\f\r]
/w 字母、数字、下划线[A-z0-9_],/W (字母、数字、下划线)[^A-z0-9_]

特殊符号
[] 范围引用:[abc](a或b或c)
- 既可表示范围,也可表示特殊符号-:[0-9-](匹配数字和特殊符号-,:2019-01-01)
|,任意条件中符合某个条件等式成立:/a|b|c/(a或b或c)
() 分组:(abc){n}(abc出现n次)
^ 既可表示取反:[^a](除了a),也可表示开头引用:^a(以a开头)
$ 既可表示结尾引用:a$(以a结尾),也可表示分组反向引用
如:2019-01-01,通过表达式(/(\d{4})-\(d{2})-(\d{2})/g)分组,
$n 表示获取第n个分组,:$1=2019,$2=01,$3=01
?: 忽略分组,:通过表达式(/(?:\d{4})-\(d{2})-(\d{2})/g)分组,$1=01
?= 正向前瞻,如表达式(/\d(?=\d)/g)表示数字后一位是数字
?! 负向前瞻,如表达式(/\d(?!\d)/g)表示数字后一位不是数字

量词
? 出现零或一次
+ 出现一或多次
* 出现任意次数
{n} 出现n次
{n,m} 出现n到m次
{n,} 至少出现n次

贪婪模式(默认)
\d{n,m} -> 往多的次数匹配数字,匹配m次,称之为贪婪
非贪婪模式(表达式后接?符号)
\d{n,m}? -> 往少的次数匹配数字,匹配n次,称之为非贪婪

七,定时器和延时加载

var timer = setInterval(function(){},millisecond); -> 创建一个定时器
clearInterval(timer); -> 移除一个定时器
var timer = setTimeout(function(){},millisecond); -> 延迟加载
clearTimeout(timer); -> 取消延迟加载

var date = new Date(); -> 创建日期
date.getYear(); -> 获取两位年份
date.getFullYear(); -> 获取四位年份
date.getMonth(); -> 获取月份(0-11)
date.getDate(); -> 获取月的日(1-31)
date.getDay(); -> 获取星期几(0-6,0是星期日)
date.getHours(); -> 获取小时(0-23)
date.getMinutes(); -> 获取分钟(0-59)
date.getSeconds(); -> 获取秒(0-59)
date.getMilliseconds(); -> 获取毫秒(0-999)
date.toLocaleDateString(); -> 获取日期
date.toLocaleString(); -> 获取日期和时间

Date.prototype.Format = function (fmt) {
    var o = {
        "M+": this.getMonth() + 1,                   //月份
        "d+": this.getDate(),                        //日
        "h+": this.getHours(),                       //小时
        "m+": this.getMinutes(),                     //分
        "s+": this.getSeconds(),                     //秒
        "q+": Math.floor((this.getMonth() + 3) / 3), //季度
        "S": this.getMilliseconds()                  //毫秒
        };
        if (/(y+)/.test(fmt))
          fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var k in o)
          if (new RegExp("(" + k + ")").test(fmt))
          fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
          return fmt;
    };
var day = date.Format("yyyy-MM-dd HH-mm-ss");

八,作用域

全局作用域:包含在<script></script>里的代码,在页面打开时创建,在页面关闭时销毁。里面含有一个全局对象window,它代表浏览器的窗口,供我们直接使用。所有创建的变量都会作为window对象的属性保存,所有创建的函数都会作为window对象的方法保存。

<script>
    var object = "scope"; -> 定义一个全局变量
    console.log(object); | console.log(window.object); -> 两种调用方式等价
    obj = "scope"; -> 不通过var声明一个全局变量,直接作为window对象的属性
    console.log(window.obj); -> 变量作为window对象的属性

    function fun(){}; -> 定义一个全局函数
    fun(); | window.fun(); -> 两种调用方式等价
</script>

<script>
    console.log(object); -> undefined
    var object = "obj"; -> var的作用是变量提前声明

    var object; -> 等价上面代码
    console.log(object);
    object = "obj";
</script>

<script>
    funA(); -> 可调用
    function funA(){}; -> 函数提前声明(优先加载)
    funA(); -> 可调用
    
    funB(); -> 不可调用,函数未创建好
    var funB = function(){}; -> 函数普通声明
    funB(); -> 可调用
</script>

函数作用域:调用函数时,创建作用域,执行完毕时,销毁作用域。每次调用函数都会创建一个新的作用域,每个作用域之间是独立的。函数作用域可以访问到全局作用域的变量,全局作用域不能访问到函数作用域的变量。函数获取一个变量时,先从自身的作用域开始找,再往上逐层地找,如果找不到该变量会报引用异常(ReferenceError)。

<script>
    var object = "obj";
    function funA(){
        console.log(object); -> 成立,函数作用域获取全局作用域的变量
    }

    function funB(){
        var object = "obj";
    }
    console.log(object); -> 不成立,全局作用域不能获取函数作用域的变量

    var object = "obj";
    function funC(){
        console.log(object); -> undefined,优先获取自身作用域的变量
        var object = "obj"; -> 变量提前声明
    }

    var object = "obj";
    function funD(object){ -> 形参等价于 var object
        console.log(object); -> undefined
    }

    function funE(){
        object = "obj"; -> 在函数中声明全局变量
    }
    console.log(object); -> 成立,在全局作用域获取全局变量
</script>

局变量在函数里的作用域:当全局变量作为传参带入函数时,函数的入参可以理解为全局变量的复制品,对入参重新赋值时,该值的作用范围在函数内部,不会影响到全局变量原有的值。但当操作入参的方法时,修改的属性会同时作用到全局变量。

var global = [1,2,3];

function quote(g){
  g.push(4,5); -> 操作对象方法,影响全局变量原来的值
}
quote(global);
console.log(global); -> [1,2,3,4,5]

function assign(g){
   g = [3,2,1]; -> 重新赋值,不影响全局变量原来的值
}
assign(global);
console.log(global); -> [1,2,3]

九,浏览器对象

1、window:浏览器窗口对象
window.closed; -> 窗口是否关闭
window.frames; -> 返回iframe集合
window.innerWidth; -> 窗口内容区域宽度
window.innerHeight; -> 窗口内容区域高度
window.outerWidth; -> 窗口总宽度,包括工具条和滚动条
window.outerHeight; -> 窗口总高度,包括工具条和滚动条
window.name; -> 窗口名称
window.parent; -> 返回父窗口
window.top; -> 返回最顶层窗口
window.btoa(); -> 创建base-64编码的字符串
window.atob(); -> 创建base-64解码的字符串
window.open(); -> 打开新的浏览器窗口
window.close(); -> 关闭浏览器窗口
window.stop(); -> 停止窗口加载

2、navigator:浏览器信息对象
navigator.appCodeName; -> 返回浏览器的代码名
navigator.appName; -> 返回浏览器的名称
navigator.appVersion; -> 返回浏览器的平台和版本信息
navigator.cookieEnabled; -> 返回浏览器是否启用COOKIE的布尔值
navigator.platform; -> 返回运行浏览器的操作系统平台
navigator.userAgent; -> 返回由客户机发送服务器的user-agent的值

3、screen:客户端屏幕信息对象
screen.width; -> 返回屏幕总宽度
screen.height; -> 返回屏幕总高度
screen.availWidth; -> 返回屏幕宽度,不包括任务栏
screen.availHeight; -> 返回屏幕高度,不包括任务栏
screen.pixelDepth; -> 返回屏幕的颜色分辨率
screen.colorDepth; -> 返回目标设备或缓冲器上的调色板的比特深度

4、history:浏览器访问历史对象
history.length; -> 返回历史列表的长度
history.back(); -> 加载历史列表中的前一个网页
history.forward(); -> 加载历史列表中的下一个网页
history.go(index); -> 加载历史列表中的第几个网页

5、location:当前URL信息对象
location.hash; -> 返回URL锚的部分
location.host; -> 返回URL的主机名和端口
location.hostname; -> 返回URL的主机名
location.href; -> 返回完整的URL
location.pathname; -> 返回的URL路径名
location.port; -> 返回URL服务器使用的端口号
location.protocol; -> 返回URL协议
location.search; -> 返回URL的查询部分
location.assign(URL); -> 载入一个新的文档
location.reload(); -> 重新载入当前文档
location.replace(URL); -> 用新的文档替换当前文档

6、document:HTML文档节点对象
document.body; -> body元素
document.cookie; -> Cookie集合
document.doctype; -> 文档类型声明
document.domain; -> 文档的域名
document.documentMode; -> 浏览器渲染文档的模式
document.title; -> 文档的标题
document.URL; -> 文档的地址
document.readyState; -> 返回文档加载状态
document.referrer; -> 载入当前文档的文档的 URL
document.normalize(); -> 删除空文本节点
document.normalizeDocument(); -> 删除空文本节点

7、会话存储和本地存储
localStorage.setItem(key,value); -> 本地存值
localStorage.getItem(key); -> 本地取值
sessionStorage.setItem(key,value); -> 会话存值
sessionStorage.getItem(key); -> 会话取值

8、console:日志对象
console.assert(boolean,message); -> 断言为false,在控制台输出信息
console.count(); -> 记录调用该方法的次数
console.clear(); -> 清除控制台上的信息
console.group(); -> 控制台信息分组开头
console.groupEnd(); -> 控制台信息分组结尾
console.groupCollapsed(); -> 控制台创建信息分组
console.table(["A","B","C"]); -> 以表格形式显示数据
console.time(); -> 开始计时
console.timeEnd(); -> 计时结束
console.trace(); -> 当前执行的代码在堆栈中的调用路径
console.info(message); -> 控制台输出普通信息
console.log(message); -> 控制台输出日志信息
console.warn(message); -> 控制台输出警告信息
console.error(message); -> 控制台输出错误信息
Last Updated: 9/18/2019, 12:15:27 AM