这里写目录标题
数据类型
原始类型(基础类型)
数值;字符串;布尔值
合成类型(复合类型)
对象:因为一个对象往往是多个原始类型的值的合成,可以看作是一个存放各种值的容器。
undefined和null:一般将它们看成两个特殊值。null一般代表对象为“没有‘,undefined一般代表数值为”没有“。
ES6新出的Symbol BinInt
Symbol 。这种类型的对象永不相等,即始创建的时候传入相同的值,可以解决属性名冲突的问题,做为标记。
bigInt。是指安全存储、操作大整数。(但是很多人不把这个做为一个类型)。
运算符之布尔运算符
用于将表达式转为布尔值,取反运算符 !、且运算符 &&、或运算符 ||
取反运算符(!)
对于非布尔值,取反运算符会将其转为布尔值,以下六个值取反后为true,其他值都为false。
undefined、null、false、0、NaN、空字符串(‘’)
注:NaN属性代表一个”不是数字“的值,这个特殊的值是因为运算不能执行而导致的,不能执行的原因是 运算对象之一非数字或者运算结果非数字。NaN类型为Number,NaN和任何东西比较(===)包括他自己都是false
break和continue
break 跳出整个循环,continue跳出本次循环,进入下次循环
字符串方法
charAt()
charAt 方法返回指定位置的字符,参数是从 0 开始编号的
如果参数为负数,或大于等于字符串的长度, charAt 返回空字符串
concat()
concat 方法用于连接两个字符串,返回一个新字符串,不改变原字符串。该方法可以接受多个参数。
如果参数不是字符串, concat 方法会将其先转为字符串,然后再连接。
concat和+的区别:
concat不管什么类型直接合并成字符串
加号遇到数字类会做运算,遇到字符串相连接
substring()
substring 方法用于从原字符串取出子字符串并返回,不改变原字符串。
它的第一个参数表示子字符串的开始位置,第二个位置表示结束位置(返回结果不含该位置)
如果省略第二个参数,则表示子字符串一直到原字符串的结束
如果第一个参数大于第二个参数, substring 方法会自动更换两个参数的位置
如果参数是负数, substring 方法会自动将负数转为0
substr()
substr 方法用于从原字符串取出子字符串并返回,不改变原字符串,跟 substring 方法的作用相同
substr 方法的第一个参数是子字符串的开始位置(从0开始计算),第二个参数是子字符串的长度
如果省略第二个参数,则表示子字符串一直到原字符串的结束
如果第一个参数是负数,表示倒数计算的字符位置。如果第二个参数是负数,将被自动转为0,因此会返回空字符串
indexOf()
indexOf 方法用于确定一个字符串在另一个字符串中第一次出现的位置,返回结果是匹配开始的位置。如果返回 -1 ,就表示不匹配
indexOf 方法还可以接受第二个参数,表示从该位置开始向后匹配
trim()
trim 方法用于去除字符串两端的空格,返回一个新字符串,不改变原字符串
该方法去除的不仅是空格,还包括制表符( \t 、 \v )、换行符( \n )和回车符( \r )
ES6扩展方法:trimEnd() 和 trimStart() 方法
" itbaizhan ".trimEnd(); // itbaizhan
" itbaizhan ".trimStart(); // itbaizhan
split()
split 方法按照给定规则分割字符串,返回一个由分割出来的子字符串组成的数组
如果分割规则为空字符串,则返回数组的成员是原字符串的每一个字符。
如果省略参数,则返回数组的唯一成员就是原字符串
split 方法还可以接受第二个参数,限定返回数组的最大成员数。
for in 和 for of 数组遍历
两者都可以用于遍历,不过for in遍历的是数组的索引(index)即键名,而for of遍历的是数组元素值(value)
for in:
1、索引是字符串型的数字,因而不能直接进行几何运算
2、遍历顺序可能不是实际的内部顺序
3、for in会遍历数组所有的可枚举属性,包括原型。例如的原型方法method和name属性
for of:
for of不支持普通对象,想遍历对象的属性,可以用for in循环, 或内建的Object.keys()方法:
Object.keys(myObject)获取对象的实例属性组成的数组,不包括原型方法和属性
for (var key of Object.keys(Object))
console.log(key + ": " + Object[key])
一般用for in遍历对象 for of 遍历数组
数组方法
数组静态方法 Array.isArray()
Array.isArray 方法返回一个布尔值,表示参数是否为数组。它可以弥补typeof 运算符的不足
push()/pop()
push 方法用于在数组的末端添加一个或多个元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组
pop 方法用于删除数组的最后一个元素,并返回该元素。注意,该方法会改变原数组
shift()/unshift()
shift 方法用于删除数组的第一个元素,并返回该元素。注意,该方法会改变原数组,shift 方法可以遍历并清空一个数组
unshift 方法用于在数组的第一个位置添加元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组
unshift 方法可以接受多个参数,这些参数都会添加到目标数组头部
join()
join 方法以指定参数作为分隔符,将所有数组成员连接为一个字符串返回。如果不提供参数,默认用逗号分隔
如果数组成员是 undefined 或 null 或空位,会被转成空字符串
[undefined, null].join('#') // '#'
['a',, 'b'].join('-') // 'a--b'
数组的 join 配合字符串的 split 可以实现数组与字符串的互换
concat()
concat 方法用于多个数组的合并。它将新数组的成员,添加到原数组成员的后部,然后返回一个新数组,原数组不变
除了数组作为参数, concat 也接受其他类型的值作为参数,添加到目标数组尾部。
reverse()
reverse 方法用于颠倒排列数组元素,返回改变后的数组。注意,该方法将改变原数组
indexOf()
indexOf 方法返回给定元素在数组中第一次出现的位置,如果没有出现则返回 -1
indexOf 方法还可以接受第二个参数,表示搜索的开始位置
对象
对象就是一组“键值对”(key-value)的集合,是一种无序的复合数据集合
如果一个属性的值为函数,通常把这个属性称为“方法”,它可以像函数那样调用
如果属性的值还是一个对象,就形成了链式引用
Math对象
Math是 JavaScript 的原生对象,提供各种数学功能
Math.abs() 返回参数值的绝对值
Math.max 方法返回参数之中最大的那个值, Math.min 返回最小的那个值。如果参数为空, Math.min 返回 Infinity , Math.max 返回 -Infinity 。
Math.floor 方法返回小于参数值的最大整数,Math.ceil 方法返回大于参数值的最小整数
Math.random() 返回0到1之间的一个伪随机数,可能等于0,但是一定小于1
Date对象
Date 对象是 JavaScript 原生的时间库。它以1970年1月1日00:00:00作为时间的零点,可以表示的时间范围是前后各1亿天(单位为毫秒)
Date.now 方法返回当前时间距离时间零点(1970年1月1日 00:00:00UTC)的毫秒数,相当于 Unix 时间戳乘以1000
时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。
Date 对象提供了一系列 get* 方法,用来获取实例对象某个方面的值
getTime():返回实例距离1970年1月1日00:00:00的毫秒数
getDate():返回实例对象对应每个月的几号(从1开始)
getDay():返回星期几,星期日为0,星期一为1,以此类推
getYear():返回距离1900的年数
getFullYear():返回四位的年份
getMonth():返回月份(0表示1月,11表示12月)
getHours():返回小时(0-23)
getMilliseconds():返回毫秒(0-999)
getMinutes():返回分钟(0-59)
getSeconds():返回秒(0-59)
document对象_方法/获取元素
document.getElementsByTagName()
document.getElementsByTagName 方法搜索 HTML 标签名,返回符合条件的元素。它的返回值是一个类似数组对象( HTMLCollection 实例),可以实时反映 HTML 文档的变化。如果没有任何匹配的元素,就返回一个空集
var paras =document.getElementsByTagName('p')
如果传入 * ,就可以返回文档中所有 HTML 元素
document.getElementsByClassName()
document.getElementsByClassName 方法返回一个类似数组的对象( HTMLCollection 实例),包括了所有 class 名字符合指定条件的元素,元素的变化实时反映在返回结果中
由于 class 是保留字,所以 JavaScript 一律使用 className 表示 CSS 的 class,参数可以是多个 class ,它们之间使用空格分隔
var paras =document.getElementsByClassName('foo bar')
document.getElementsByName()
document.getElementsByName 方法用于选择拥有 name 属性的 HTML 元素(比如 、 、 等),返回一个类似数组的的对象( NodeList 实例),因为 name 属性相同的元素可能不止一个
// 表单为 <form name="itbaizhan"></form>
var forms =document.getElementsByName('itbaizhan');
document.getElementById()
document.getElementById 方法返回匹配指定 id 属性的元素节点。如果没有发现匹配的节点,则返回 null
注意,该方法的参数是大小写敏感的。比如,如果某个节点的 id 属性是 main ,那么 document.getElementById(‘Main’) 将返回 null
document.querySelector()
document.querySelector 方法接受一个 CSS 选择器作为参数,返回匹配该选择器的元素节点。如果有多个节点满足匹配条件,则返回第一个匹配的节点。如果没有发现匹配的节点,则返回 null
var el1 = document.querySelector('.myclass');
document.querySelectorAll()
document.querySelectorAll 方法与 querySelector 用法类似,区别是返回一个NodeList 对象,包含所有匹配给定选择器的节点
document对象_方法/创建元素
document.createElement()
document.createElement 方法用来生成元素节点,并返回该节点
var newDiv = document.createElement('div');
document.createTextNode()
document.createTextNode 方法用来生成文本节点( Text 实例),并返回该节点。它的参数是文本节点的内容
var newDiv = document.createElement('div');
var newContent =document.createTextNode('Hello');
newDiv.appendChild(newContent);
document.createAttribute()
document.createAttribute 方法生成一个新的属性节点( Attr 实例),并返回它
var attribute =document.createAttribute(name);
var root = document.getElementById('root');
var it =document.createAttribute('itbaizhan');
it.value = 'it';
root.setAttributeNode(it);
Element对象_属性
Element对象对应网页的 HTML 元素。每一个 HTML 元素,在DOM 树上都会转化成一个Element节点对象(以下简称元素节点)
Element.id
Element.id 属性返回指定元素的 id 属性,该属性可读写
// HTML 代码为 <p id="foo">
var p = document.querySelector('p');
p.id // "foo"
Element.className
className 属性用来读写当前元素节点的 class 属性。它的值是一个字符串,每个 class 之间用空格分割
// HTML 代码 <div class="one two three"id="myDiv"></div>
var div = document.getElementById('myDiv');
div.className
Element.classList
classList 对象有下列方法
add() :增加一个 class。
remove() :移除一个 class。
contains() :检查当前元素是否包含某个 class。
toggle() :将某个 class 移入或移出当前元素
var div = document.getElementById('myDiv');
div.classList.add('myCssClass');
div.classList.add('foo', 'bar');
div.classList.remove('myCssClass');
div.classList.toggle('myCssClass'); // 如果myCssClass 不存在就加入,否则移除
div.classList.contains('myCssClass'); // 返回true 或者 false
Element.innerHTML
Element.innerHTML 属性返回一个字符串,等同于该元素包含的所有HTML 代码。该属性可读写,常用来设置某个节点的内容。它能改写所有元素节点的内容,包括 和 元素
el.innerHTML = '';
Element.innerText
innerText 和 innerHTML 类似,不同的是 innerText 无法识别元素,会直接渲染成字符串
Element获取元素位置
Element.clientHeight,Element.clientWidth
Element.clientHeight 属性返回一个整数值,表示元素节点的 CSS 高度(单位像素),只对块级元素生效,对于行内元素返回 0 。如果块级元素没有设置 CSS 高度,则返回实际高度。如果有水平滚动条,还要减去水平滚动条的高度。注意,这个值始终是整数,如果是小数会被四舍五入。
Element.clientWidth 属性返回元素节点的 CSS 宽度,同样只对块级元素有效,也是只包括元素本身的宽度和 padding ,如果有垂直滚动条,还要减去垂直滚动条的宽度。注意,这个值始终是整数,如果是小数会被四舍五入。
除了元素本身的高度,它l俩还包括 padding 部分,但是不包括 border 、 margin 。
document.documentElement 的 clientHeight 属性,返回当前视口的高度(即浏览器窗口的高度)。 document.body 的高度则是网页的实际高度。
// 视口高度
document.documentElement.clientHeight
// 网页总高度
document.body.clientHeight
Element.scrollHeight,Element.scrollWidth
Element.scrollHeight 属性返回一个整数值(小数会四舍五入),表示当前元素的总高度(单位像素),它包括 padding ,但是不包括 border 、 margin 以及水平滚动条的高度(如果有水平滚动条的话)
Element.scrollWidth 属性表示当前元素的总宽度(单位像素),其他地方都与 scrollHeight 属性类似。这两个属性只读
整张网页的总高度可以从 document.documentElement 或 document.body 上读取
// 返回网页的总高度
document.documentElement.scrollHeight
document.body.scrollHeight
Element.scrollLeft,Element.scrollTop
Element.scrollLeft 属性表示当前元素的水平滚动条向右侧滚动的像素数量,
Element.scrollTop 属性表示当前元素的垂直滚动条向下滚动的像素数量。对于那些没有滚动条的网页元素,这两个属性总是等于0
如果要查看整张网页的水平的和垂直的滚动距离,要从document.documentElement 元素上读取
document.documentElement.scrollLeft
document.documentElement.scrollTop
Element.offsetHeight,Element.offsetWidth
Element.offsetHeight 属性返回一个整数,表示元素的 CSS 垂直高度(单位像素),包括元素本身的高度、padding 和 border,以及水平滚动条的高度(如果存在滚动条)。
Element.offsetWidth 属性表示元素的 CSS 水平宽度(单位像素),其他都与 Element.offsetHeight 一致。
这两个属性都是只读属性,只比 Element.clientHeight 和 Element.clientWidth 多了边框的高度或宽度。如果元素的 CSS 设为不可见(比如 display: none; ),则返回 0
Element.offsetLeft,Element.offsetTop
Element.offsetLeft 返回当前元素左上角相对于 Element.offsetParent 节点的水平位移, Element.offsetTop 返回垂直位移,单位为像素。通常,这两个值是指相对于父节点的位移
操作CSS
操作 CSS 样式最简单的方法,就是使用网页元素节点的 setAttribute 方法直接操作网页元素的 style 属性
div.setAttribute('style','background-color:red;' + 'border:1px solidblack;');
事件处理程序
HTML事件处理
<div id="div">
<button id="btn1"onclick="demo()">按钮</button>
</div>
function demo(){
alert("hello html事件处理");
}
DMO0级事件处理
<div id="div">
<button id="btn1"onclick="demo()">按钮</button>
</div>
var btn1=document.getElementById("btn1");
btn1.onclick=function(){alert("Hello,DOM0级事件处理程序1");}//被覆盖掉
btn1.onclick=function(){alert("Hello,DOM0级事件处理程序2");}
DOM2级事件处理
<div id="div">
<button id="btn1"onclick="demo()">按钮</button>
</div>
var btn1=document.getElementById("btn1");
btn1.addEventListener("click",demo1);
btn1.addEventListener("click",demo2);
btn1.addEventListener("click",demo3);
function demo1(){
alert("DOM2级事件处理程序1")
}
function demo2(){
alert("DOM2级事件处理程序2")
}
function demo3(){
alert("DOM2级事件处理程序3")
}
btn1.removeEventListener("click",demo2);
定时器之 setTimeout()
定时执行代码的功能,叫做定时器(timer),主要由 setTimeout() 和 setInterval() 这两个函数来完成。它们向任务队列添加定时任务
setTimeout 函数用来指定某个函数或某段代码,在多少毫秒之后执行。它返回一个整数,表示定时器的编号,以后可以用来取消这个定时器。
setTimeout 函数接受两个参数,第一个参数 func|code 是将要推迟执行的函数名或者一段代码,第二个参数 delay 是推迟执行的毫秒数
var timerId = setTimeout(func|code, delay);
注意:如果回调函数是对象的方法,那么setTimeout 使得方法内部的 this 关键字指向全局环境,而不是定义
时所在的那个对象
定时器可以进行取消, clearTimeout(id);
定时器之 setInterval()
setInterval 函数的用法与 setTimeout 完全一致,区别仅仅在于 setInterval 指定某个任务每隔一段时间就执行一次,也就是无限次的定时执行
var timer = setInterval(function() {console.log(2);}, 1000)
定时器可以进行取消,clearInterval(id);
防抖(debounce)
防抖严格算起来应该属于性能优化的知识,但实际上遇到的频率相当高,处理不当或者放任不管就容易引起浏览器卡死
从滚动条监听的例子说起
function showTop () {
var scrollTop =document.documentElement.scrollTop;
console.log('滚动条位置:' + scrollTop);
}
window.onscroll = showTop
在运行的时候会发现存在一个问题:这个函数的默认执行频率,太!高!了!然而实际上我们并不需要如此高频的反馈,毕竟浏览器的性能是有限的
基于上述场景,首先提出第一种思路:在第一次触发事件时,不立即执行函数,而是给出一个期限值比如200ms,然后
如果在200ms内没有再次触发滚动事件,那么就执行函数
如果在200ms内再次触发滚动事件,那么当前的计时取消,重新开始计时
效果:如果短时间内大量触发同一事件,只会执行一次函数
实现:既然前面都提到了计时,那实现的关键就在于setTimeout这个函数,由于还需要一个变量来保存计时,考虑维护全局纯净,可以借助闭包来实现
function debounce(fn,delay){
let timer = null //借助闭包
return function()
{
if(timer){
clearTimeout(timer)
}
timer = setTimeout(fn,delay) // 简化写法
}
}
// 然后是旧代码
function showTop () {
var scrollTop =document.documentElement.scrollTop;
console.log('滚动条位置:' + scrollTop);
}
window.onscroll = debounce(showTop,300)
防抖定义
对于短时间内连续触发的事件(上面的滚动事件),防抖的含义就是让某个时间期限(如上面的1000毫秒)内,事件处理函数只执行一次
闭包
要理解闭包,首先必须理解Javascript特殊的变量作用域。
变量的作用域无非就是两种:全局变量和局部变量。
Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。
另一方面,在函数外部自然无法读取函数内的局部变量
这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!
如何从外部读取局部变量?
出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。
那就是在函数的内部,再定义一个函数。
function f1(){
var n=999;
function f2(){
alert(n);//999
}
}
在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1就是不可见的。这就是Javascript语言特有的"链式作用域"结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。
既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!
function f1(){
var n=999;
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
代码中的f2函数,就是闭包。闭包就是能够读取其他函数内部变量的函数。
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
注意:
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
节流(throttle)
如果在限定时间段内,不断触发滚动事件(比如某个用户闲着无聊,按住滚动不断的拖来拖去),只要不停止触发,理论上就永远不会输出当前距离顶部的距离
我们可以设计一种类似控制阀门一样定期开放的函数,也就是让函数执行一次后,在某个时间段内暂时失效,过了这
段时间后再重新激活(类似于技能冷却时间)
效果:如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效
借助setTimeout来做一个简单的实现,加上一个状态位valid来表示当前函数是否处于工作状态
function throttle(fn,delay){
let valid = true
return function() {
if(!valid){
//休息时间 暂不接客
return false
}
// 工作时间,执行函数并且在间隔期内把状态位设为无效
valid = false
setTimeout(function(){
fn()
valid = true;
}, delay)
}
}
function showTop () {
var scrollTop =document.documentElement.scrollTop;
console.log('滚动条位置:' + scrollTop);
}
window.onscroll = throttle(showTop,300)
如果一直拖着滚动条进行滚动,那么会以300ms的时间间隔,持续输出当前位置和顶部的距离
适用场景
1、搜索框input事件,例如要支持输入实时搜索可以使用节流方案(间隔一段时间就必须查询相关内
容),或者实现输入间隔大于某个值(如500ms),就当做用户输入完成,然后开始搜索,具体使
用哪种方案要看业务需求
2 、页面resize事件,常见于需要做页面适配的时候。需要根据最终呈现的页面情况进行dom渲染(这
种情形一般是使用防抖,因为只需要判断最后一次的变化情况)