javascript编程基础 案例,javascript基础入门案例
大家好,小编来为大家解答以下问题,javascript编程基础 案例,javascript基础入门案例,现在让我们一起来看看吧!
第一章 JavaScript简介
JavaScript实现组成:
- ECMAScript(核心)
- DOM(文档对象模型)
- BOM(浏览器对象模型)
第二章 在HTML中使用
- 可以添加
defer
关键字延迟执行,在文档被加载并完全解析后,类似与DOMContentLoaded
事件但是在DOMContentLoaded
事件之前,多个defer
脚本是按顺序调用的(但在现实中都不一定). - 可以添加
async
关键字异步加载,不会阻塞HTML的解析,会在onload
事件前,可能在DOMContentLoaded
前也可能在之后,多个异步不能保证顺序. - 在不支持脚本或禁用脚本时使用
no
使脚本平稳退化,内部可以使用HTML标签
onload事件在页面被完全加载完成后调用
DOMContentLoaded在HTML完全加载并解析后调用,不会等待样式表、图片等
第三章 基本概念
语法
- 始终在控制语句中使用代码块,即使只有一条控制语句(最佳实践)
- 八进制字面量在严格模式下是无效的
-
isNaN
会将值尝试转化为数值(调用Number转换)再进行判断 -
Number(null)
转换结果为0,Number(undefined)
转换结果为NaN,Number()
转换字符串类型复杂且不科学(比如Number("")
为0),使用parseInt()
转换字符串更好,也可以使用一元+操作符,效果与Number()
相同一元-与+规则相同,最后转换的数值添加- - 使用
toString
转换值为字符串,null和undefined没有这个方法(在不知道类型时可以使用String()
方法),转换数字类型时可以传入参数为转换的基数 -
propertyIsEnumerable
检查属性是否可迭代 - 在进行位操作时
NaN
和undefined
会被当做0,其他类型调用Number()
后进行位操作
按位操作符 | 解释 |
---|---|
| | 按位或 |
& | 按位与 |
~ | 按位取非 |
^ | 按位异或 |
<< | 左移(不会影响符号位),空位补0 |
>> | 有符号右移,空位以符号位填充 |
>>> | 无符号右移 |
无符号右移会将符号位看做数值,有符号位移操作忽略符号位
- 相等操作符:先转换后比较,全等操作符:仅比较不转换,null和undefined在比较前不进行转换.
语句
- 可以使用label语句配合break、continue退出循环
var num = 0;
outermost: for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
if (i == 5 && j == 5) {
break outermost;
}
num++;
}
}
alert(num);//55 退出整个循环
var num = 0;
outermost: for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
if (i == 5 && j == 5) {
console.log(num)
continue outermost;
}
num++;
}
}
alert(num); //95 强制退出内部循环,进行外部循环
- 使用
with
将代码专用域绑定到特定对象下,严格模式不允许使用with
语句,大量with
导致性能下降,不建议使用
var obj={a:1,b:2};
with(obj){
var getA=a;
var getB=b;
}
第四章 变量、作用域和内存问题
- 所有引用类型都是object的实例
- typeof 正则表达式为object
-
[1,2,]
在IE9以下为3项,最后一项为undefined,以逗号的个数判定 - 检测数组使用
Array.isArray()
,instanceof
的缺陷在于规定为一个全局环境,当使用框架时,框架A向框架B传递数组,两者的构造函数不同. - 调用数组的
toString()
实际上是对里边的每项使用toString
方法然后用逗号分割拼接,调用valueOf()
返回的还是数组. - 函数作用域:也可以说是Function中的[[scope]]属性,在函数定义时被创建,并且不会改变,闭包也是这个时候被创建,及[[scope]]属性中的closure属性,是包含对外部环境变量引用的对象。需要区分于作用域链,书中说的作用域链指包含活动对象的一条链,其配合上下文进行工作GPT改写。
第五章 引用类型
Date类型
通过特定日期创建Date对象需传入毫秒数,Date.parse()
和Date.UTC()
将特定日期解析为毫秒数
console.log(Date.parse("2019-11-24T18:09:00"))//根据日期解析为日期对象
console.log(new Date(Date.parse("2019-11-24T18:09:00")))
console.log(new Date("2019-11-24T18:12:00"))//直接传入内部会调用Date.parse()
console.log(Date.UTC(2019,10,24,18,14,00))//2019年11月
console.log(new Date(2019,10,24,18,14,00))//直接传入内部会调用Date.UTC()
上述方法返回的都是格林时间,如果要根据本地时间返回本地时间,有如下方法:
console.log(new Date('2020-04-18 17:50:00 GMT'))
console.log(new Date('2020-04-18 17:50:00 UTC'))
console.log(new Date(Date.UTC(2020,3,18,17,50,0)))
console.log(new Date().toLocaleString())
不同宿主环境返回值不同,最好还是自己解析把!!
RegExp类型
- 正则表达式
toString()
、toLocaleString()
返回对象字面量的字符串形式(String类型),valueOf()
返回正则本身(Object 类型) - exec方法返回第一个匹配项为模式匹配的内容,接下来为第一个捕获项、第二个捕获项。。。。,regexp实例中存放有
lastIndex
保存下一个匹配开始位置(在IE9以下即使为非全局模式下lastIndex
每次都会变化) - 命名捕获
const reg = /(?<year>\d{4})-(?<month>\d{2})/;
Function类型
- 函数表达式声明添加分号,就像普通声明一样(最佳实践),不推荐构造函数(Function)声明函数,会解析两次,一次解析ECMAScript,一次解析字符串,影响性能.
- 使用递归时,最好使用
arguments.callee
调用,避免函数名与执行函数的紧密耦合 - caller属性保存着调用当前函数的函数的引用,如果为window,返回null.严格模式下访问callee、caller均会报错,
function outer(){
console.log(arguments.callee.caller)//null
inner();
}
function inner(){
console.log(arguments.callee.caller);//[Function outer] 为了避免紧耦合使用arguments.callee
}
outer();
基本包装类型
- 基本类型调用方法步骤:
- 创建实例
- 调用方法
- 销毁实例
- Number类型方法:
-
toFixed()
传入参数,保留小数点后几位 -
toExponential()
传入参数,保留小数点后几位(以指数形式表示) -
toPrecision()
传入参数,代表数值表示的位数,会根据情况使用toFixed
和toExponential
- String类型
- substring()将所有负参数转化为0,substr()将第二个负参数转化为0
- split方法接收第二个参数指定数组大小,split可以使用正则
- replace方法函数形式第一个参数为匹配字符串、第二个后为捕获项,最后两个是匹配项位置和原始字符串(与exec类似,只是exec没有最后两个参数)
"agkg45gagn78agn5g".replace(/(\d)+/g,function(all,catch1,pos,str{
console.log(`all:${all},catch:${catch1},pos:${pos},str:${str}`)
})
all:45,catch:5,pos:4,str:agkg45gagn78agn5g
all:78,catch:8,pos:10,str:agkg45gagn78agn5g
all:5,catch:5,pos:15,str:agkg45gagn78agn5g
-
a.localeCompare(b)
a<b返回-1、 a===b返回0 、a>b返回1 -
String.fromCharCode()
返回字符编码转换后的字符串alert(String.fromCharCode(104, 101, 108, 108, 111)); //"hello"
单体内置对象
- 使用
encodeURI()
/decodeURI()
(对整个URI进行编码解码,对本身属于URI的不做操作)、encodeURIComponent
/decodeURLComponent
(对某部分进行解码,编码不管属不属于URI本身)进行解码和编码URI。需要注意使用哪个进行编码,只能使用对应的解码方法解码。 - 严格模式下,外部不能访问eval内部变量或者函数
- global对象作为ECMAScript的全局对象,没有提供直接访问它的接口,但是浏览器将global对象作为window对象的一部分加以实现。
第六章 面向对象的程序设计
理解对象
-
Object.defineProperty()
如果不指定enumerable(枚举)、configurable(可配置)、writable(可修改)默认值都是false - 可以使用
Object.defineProperties()
同时定义多个属性
var book = {};
Object.defineProperties(book, {
_year: { value: 2004 }, edition: { value: 1 },
year: {
get: function () {
return this._year;
},
set: function (newValue) {
if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
}
}
});
- 可以使用
Object.getOwnPropertyDeor(obj,property)
获取给定属性的描述 - 可以使用
obj.hasOwnProperty()
判断什么时候访问实例属性,什么时候访问原型属性,只有实例中存在对应的属性时才会返回true。如果想判断是否存在某个属性使用in
操作符,不管存在于原型还是实例都可以 - 重写constructor时记得将其定义为不可枚举
- 原型式继承
Object.create()
,可以不用事先预知子类构造函数,也存在共享父类引用的问题
function createObject(origin){
let superObject=function(){};
superObject.prototype=origin;
return new superObject();
}
- 组合继承的缺陷在于调用了两次父类实例,创建了两个父类属性,一个在原型上,一个在实例中
第一次:调用父类构造函数
第二次:将子类原型指向父类实例
寄生组合继承解决了这个问题,利用原型式继承的特点
function Person(name){
this.name=name;
}
function Child(name){
Person.call(this,name)
}
~function(){
let Super=Object.create(Person.prototype);
// 使用defineProperty定义的属性默认为不可枚举的(最佳实践)
Object.defineProperty(Super,constructor,{
value:Child,
// enumerable:false,
// configurable:false
})
Child.prototype=Super;
}()
console.log(new Child("forcehack"))
第七章 函数表达式
闭包
- IE9以前的DOM借鉴了COM,垃圾处处理机制使用引用计数,在处理DOM操作时不使用的DOM元素记得将其指向null
- 单例模式:只有一个实例的对象(字面量直接创建对象就是单例对象),在定义私有变量时可以使用
- 模块模式为单例创建私有变量和特权函数
var application=function createPrivate(){
var private=0;
function privateFunction(){return false};
return {
publicProperty:true,
publicFunction:function(){
private++;
privateFunction();
}
}
}();
第八章 BOM
window对象
- 使用var定义的window属性不允许使用delete删除,window定义的可以,因为var定义的window属性
configurable
不可配置 - 窗口位置
属性 | 解释 |
---|---|
screenLeft | 窗口相对于屏幕左边的位置(IE返回屏幕到窗口可见区域的距离,FF、Chrome返回到窗口的距离) |
screenTop | 窗口相对于屏幕上边的位置(IE返回屏幕到窗口可见区域的距离,FF、Chrome返回到窗口的距离) |
使用moveTo()
、moveBy()
移动窗口,可能被浏览器禁用(测试火狐、IE、谷歌最新版都不可用)
moveTo(x,y):移动到某个位置
moveBy(x,y):向右移动x,向上移动y
- 窗口大小
outerWidth
、outerHeight
:浏览器窗口大小innerWidth
、innerHeight
:视口(viewport)大小
IE9以前不支持,IE9以前以及其他浏览器可以通过dom获取视口大小
标准模式:document.documentElement.clientWidth
、document.documentElement.clientHeight
混杂模式:document.body.clientWidth
、document.body.clientHeight
通过resizeTo()
、resizeBy()
调整窗口大小(测试只有IE可用)
resizeTo(x,y):调整为宽x,高y的窗口
resizeBy(x,y):在原窗口的基础上,宽度调整x,高度调整y
- 最佳实践:setTimeout模拟setInterval实现
- 使用window.find()查找信息
第十章 DOM
IE9以下的DOM对象是以COM(组件对象模型)对象的形式创建的,所以存在IE中的DOM与原生JavaScript不一致的情况
节点层次
- 通过hasChildNodes()判断是否存在子节点比获取childNodes()判断length更有效
-
insertBefore
方法如果传递第二个参数为null,那么结果与appendChild
相同 -
normalize
方法用于标准化文本节点,有时候会创建空文本节点或者一个文本节点分成多个文本节点的情况,调用该方法可以处理这种情况(如果为空文本节点则删除,相邻的两个文本节点进行合并) -
document.domain
可以处理子域不同的跨域问题,document.referrer
指向来源页面的URL,如果域名一开始是松散的就不能在将其设置为紧绷的。 - IE9以下cloneNode会克隆事件
- IE9以下不区分ID大小写
- 通过getElementsByTagName()获取的HTMLCollection可以通过namedItem()通过元素name获取元素,也可以通过方括号获取
- IE中可以通过element.name、element.getAttribute()获取属性,其他浏览器只有基本属性可以element.name,推荐基本特性使用属性的方式获取、设置,自定义特性使用getAttribute/setAttribute
第十一章 DOM扩展
HTML5
-
document.compatMode
标准模式CSS1Compat
,混杂模式BackCompat
- outerHTML返回节点以及本身的HTML,写模式下进行替换,包括自身
-
insertAdjacentHTML
,插入位置为beforebegin
、afterbegin
、beforeend
、afterend
- 在进行元素替换时,比如
innerHTML
、outerHTML
、insertAdjacentHTML
,元素与事件处理程序之间的捆绑关系并不会一并删除,会一直保存在内存中,所以在使用这些方法之前最好先接触元素与事件之间的关系。 -
scrollIntoView
可以控制元素滚动到可视区域与顶部平齐或者尽量铺满可视区域(底部与可视区域底部平齐) ,参数为true或者不进行传递时效果为第一种,参数为false时效果为第二种 - 使用
element.contains
判断是否包含某子元素
第十二章 DOM2和DOM3
样式
- 通过JavaScript指定float时最好使用
cssFloat
,因为float是JavaScript关键字,IE11已经支持,低版本IE使用styleFloat
- style可以通过
getPropertyValue
获取属性,通过removeProperty()
移除样式属性(恢复默认值) - 通过
cssText
指定css会重写内联样式的值 - 通过
document.defaultView.getComputedStyle()
可以获取计算后属性,第一个参数为元素,第二个为伪元素字符串,如:after
如果不需要伪元素信息可以指定为null。defaultView
指向窗口 - 可以通过
document.styleSheets
获取样式表信息,通过sheet.insertRule('body{background:red}',0)
方法添加规则,第一个参数为规则字符串,第二个为插入位置。通过sheet.removeRule(0)
删除规则。
遍历
-
document.createNodeIterator(root,whatToShow,filter,false)
创建结点迭代器,使用深度优先遍历,whatToShow值在NodeFilter类型中定义NodeFilter.SHOW_ALL
、NodeFilter.SHOW_ELEMENT
、NodeFilter.SHOW_TEXT
,第三个参数用于指定自定义的NodeFilter对象,如果应该访问该对象,该方法返回NodeFilter.FILTER_ACCEPT
、NodeFilter.FILTER_SKIP
document.createNodeIterator(box,NodeFilter.SHOW_ELEMENT,function(node){
return node.tagname.toLocaleLowerCase()==='p'?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP;
},false);
通过nextNode()
和previousNode()
对迭代器进行访问,第一次调用nextNode()
返回root根节点。
- 也可以通过
document.createTreeWalker
进行遍历,与createNodeIterator
类似,但是比createNodeIterator
更方便,filter方法新增NodeFilter.FILTER_REJECT
会跳过当前节点以及其整个子树,除了nextNode
和previousNode
两个方法外,还提供了用于在不同方向上遍历DOM结构的方法
parentNode
firstChild
lastChild
nextSibling
previousSibling
范围
- 使用
document.createRange()
创建range对象,通过range.setStart(container,index)
、range.setEnd(container,index)
确定范围
操作方法:
-
range.deleteContents()
删除文档碎片 -
range,extractContents()
与deleteContents
类似,区别在于会返回删除的文档碎片 -
range.cloneContents()
与extractContents
类似,但是只是返回副本,不会删除 -
range.insertNode(node)
在范围前插入节点 -
range.surroundContents(element)
节点包围范围 -
range.collapse()
折叠范围,传递true折叠到起点,传递false折叠到终点,通过range.collapsed
查看是否已经折叠 -
range.compareBoundaryPoints()
比较范围 -
range.cloneRange()
克隆范围 -
range.detach()
将范围从文档中分离,在使用range = null
,以便垃圾回收机制进行回收
- IE8之前需要不支持
document.createRange()
,但支持类似的方法
第十三章 事件
事件类型
- 、link、img均存在load事件,link和必须添加到文档中才开始下载,而img指定src就会开始下载0
- focus和blur事件不会冒泡(但是仍然可以在捕获阶段监听),focusin和focusout可以进行冒泡
- 事件对象中存在
shiftKey
、altKey
、ctrlKey
、metaKey
,如果有相应的键被按下,相应的值为true,否则为false - 对于mouseover和mouseout事件,
relatedTarget
属性保存着相关元素,<IE9需要做兼容 -
event.detail
属性保存着在同一位置的点击次数 - 复合事件用以处理输入法编辑器(输入键盘上找不到的字符),
compositionstart
、compositionupdate
、compositionend
-
HTML5事件
-
contextmenu
右键上下文菜单(window)或者ctrl+单机(mac)触发 -
beforeunload
页面将要卸载时调用,显示消息event.returnValue=message;return message //并将消息在函数中返回
(许多浏览器会忽略该事件) -
DomContentLoaded
形成完整的DOM树之后触发 -
hashchange
,URL参数发生变化时调用
-
模拟事件
- 模拟事件通过
document.createEvent()
创建事件,也可以创建自定义事件—p405
const app = document.querySelector('#app');
app.addEventListener('click',function(){
alert(123);
})
const event = document.createEvent('MouseEvents');
event.initEvent('click',true,true,document.defaultView,0,0,0,0,0,false,false,false,false,0,null);
app.dispatchEvent(event);
第十四章 表单脚本
表单的基础知识
- 避免重复提交表单的方法
- 第一次提交表单后禁用提交按钮
- 利用onsubmit事件处理程序取消后续的表单提交操作
- 表单元素存在elements属性,保存着所有表单元素的集合
- 可以添加autofocus
文本框脚本(IE8以下基本都需要做兼容)
- input元素size特性可以指定文本框显示大小,maxlength特性可以指定最大字符数,初始值使用value标记,textarea元素初始值写在标签之间
- 可以调用
select
方法选择文本,selectionStart
、selectionEnd
保存着选择文本的位置 - 使用
setSelectionRange
方法可以进行部分文本选择,先要将焦点设置到文本框 - 剪切板事件
beforecopy
、copy
、beforecut``cut
、beforepaste
、paste
,event对象中存在clipboardData
,存在方法setData
、getData
、clearData
获取数据 - 文本框可以使用
pattern
特性指定匹配,添加required
变成必填字段 - 可以对表单使用
checkValidity
方法检测整个表单是否有效,也可以对单个字段使用 - 通过
novalidate
属性可以告诉表单不进行验证 - 为按钮添加
formnovalidate
则不进行验证提交表单
选择框脚本
- select元素可以使用
add(newoption,reloption)
添加新option -
remove(index)
移除option -
options
保存有所有option,推荐使用上述获取元素,尽量少使用DOM - 可以使用
Option
构造函数创建option选项,new Option('option text','option value')
富文本编辑–p439
- 通过嵌入空的html的iframe,并将空文档的
designMode='on'
。或者设置元素contenteditable
达到可编辑的目的 - 利用
document.execCommand
执行命令,实现富文本
第十五章 使用canvas绘图
2D上下文–p446
-
getContext('2d')
获取上下文,toDataURL('image/png')
canvas元素上绘制的图像导出(是canvas上的方法,不是上下文的)。 -
fillStyle
和strokeStyle
设置填充颜色和描边颜色 -
fillRect(x,y,width,height)
和strokeRect(x,y,width,height)
画矩形 ,使用clearRect(x,y,width,height)
清除矩形区域 - 绘制路径前需要使用
beginPath()
- 使用
fillText
和strokeText
绘制文本 - 可以使用
drawImage
绘制图像 - 也可以对绘制图形设置渐变和阴影
第十六章 HTML5脚本编程
原生拖放
- drag事件,源阶段
dragstart
、drag
、dragend
,目标阶段有dragenter
、dragover
、dragleave
或者drop
事件,阻止dragenter
、dragover
、drop
默认行为可以将设置目标为可放置目标 - 通过事件对象的
event.dataTransfer.setData('text/plain','这是传送的消息')
和event.dataTransfer.getData('text/plain')
可以达到传送消息的目的
const source = document.querySelector('#drag-source');
const target = document.querySelector('#drag-target');
source.addEventListener('dragstart',function(event){
event.dataTransfer.setData('text/plain','这是传送的消息');
})
target.addEventListener('dragenter',function(event){
event.preventDefault();
})
target.addEventListener('dragover',function(event){
event.preventDefault();
})
target.addEventListener('drop',function(event){
alert(event.dataTransfer.getData('text/plain'));
})
- 默认只有图像、链接和文本可拖动,元素可以通过
draggable
属性设置是否拖动
媒体元素
- 为媒体元素poster特性指定url可以用于加载内容期间显示图像
- timeupdate事件是currentTime被意外改变时触发,所以改变currentTime显示值,最好使用定时器
历史状态
- 可以通过hashchange事件监听URL的改变,也可以通过
window.history.pushState({name:'forcehack'},'page title','page.html')
达到管理状态的目的,浏览器不会像服务器发送请求(不卸载当前页面修改历史栈)
第二十章 JSON
- JSON数据会跳过值为undefined的数据
-
JSON.stringfy()
第二个参数为过滤器,如果为数组形式,则只返回数组中对应的键的数据,如果为函数形式,函数接收键和值两个参数,返回值,返回undefined则跳过。第三个参数为表示缩进,如果为数字类型则表示缩进多少,如果为字符串,则使用字符串中的值标记缩进 - 如果对象存在
toJSON
方法,那么JSON.stringfy
调用toJSON
方法 -
JSON.parse
也可以接收第二个参数为一个函数,同样接收键值对,返回值,返回undefined进行删除
第二十一章 Ajax与Comet–P578
- FormData使用
append(key,value)
传入数据,FormData也可以直接传入表单元素new FormData(document.forms[0])
- 可以使用
overrideMimeType(text/xml)
重写响应类别,强迫xhr对象将响应当做xml处理 - xhr支持进度事件
progress
、load
,progress
事件可以用于处理进度信息(存储在事件对象中)。
const xhr = new XMLHttpRequest();
xhr.onload = function(){
console.log(event);
console.log(JSON.parse(xhr.response));
};
xhr.open('GET','https://jsonplaceholder.typicode.com/todos',true);
xhr.send(null);
-
XMLHTTPRequest
默认实现了对CROS的支持,只要在请求时传入绝对URL即可,限制在于
- 不能使用
setRequestHeader
创建请求头 - 不能发送和接受cookie
- 不能使用
getAllResponseHeaders()
获取响应头信息(始终为空字符串)
为了区分同源还是跨源,则在本地使用时最好使用相对URL,跨源使用绝对URL,实现原理在于发送请求时,浏览器会自动发送一个Preflighted Request携带Access-Control-Request-Headers
、Access-Control-Request-Method
、Origin
CROS需要的头部信息,该请求使用OPTIONS方法,代价只是第一次发送时需要多发送一次HTTP请求
- Comet:一种服务器向页面推送数据的技术,实现方式长轮询或者HTTP流
短轮询:页面定时向服务器发送请求,看看是否有数据更新(利用setTimeout和ajax即可实现)
长轮询:页面向服务器发送请求,服务器保持连接,有数据了向页面发送数据,浏览器关闭连接,同时向服务器继续发起新请求,在页面存在期间持续不断
HTTP流:只创建一次HTTP连接,服务保持连接,周期性的向浏览器发送请求,xhr通过readystate事件监听readystate是否为3
服务器发送事件API(SSE)支持短轮询、长轮询和HTTP流,并且能在断开连接时自动确定何时连接,EventSource有一个readystate属性,0表示正在连接到服务器,1表示打开了连接,2表示关闭了连接
const source = new EventSource('myevents,php');//URL必须同源
同时有3个事件API,open
、message
、error
,默认是会保持连接,也可以说SSE适合长轮询和HTTP流,如果断开连接可以调用source,close()
WebSocket
两者选择:由于webSocket不同于HTTP,有自身的协议,所以现有服务器不能用于webSocket,是否有能力建立和维护webSocket服务器,考虑是否真的需要双向通信,如果只需读取服务器数据,SSE更好(组合XHR和SSE也能实现双向通信)
第二十二章 高级技巧
-
Object.preventExtensions()
将对象设置为防篡改对象,通过Object.isExtensible()
检测是否可扩展。但是可以修改已有属性,也可以删除 -
Object.seal()
密封对象,对象不可扩展,不可删除,通过Object.isSealed()
检测是否被密封 -
Object,freeze()
冻结对象,不可扩展,不可删除,不可修改,使用Object.isFrozen
检测是否被冻结0
第二十三章 离线应用与客户端存储—P628
-
navigator,onLine
检测是否在线同时提供online
、offline
两个事件监听网络 - appcache是从浏览器缓存中分出来的一块缓存区,如果想在其中保存数据,可以使用描述文件(mainfest file),列出需要下载和缓存的资源
CACHE MAINFEST
#Comment
file.js
file.css
需要与页面关联可以使用在html元素中指定mainfest属性<html mainfest = '/offline.mainfest'>
,相应的API查看缓存正在做什么是applicationCache
对象,可以通过applicationCache.update()
触发检查更新
- 有时为了绕开浏览器单域名下对cookie个数的限制,可以使用子cookie,如
name=name1=value1&name2=value2
//name后边内容作为name的值出现,算作一个cookie,即子cookie的概念
第二十四章 最佳实践—P668
- 使用减值迭代
- 使用后测试循环
- 展开循环(Duff技术)
- switch语句更快
- 使用innerHTML,innerHTML会在后台建立DOM调用创建DOM,不是通过JavaScript,更快
- 注意HTMLCollection
getElementsByTagName
attributes
childNodes
-
document.forms
、document.images
等
- HTTP压缩,代码压缩(YUI)
第二十五章 新兴API
- 在下一次页面重绘前调用
requestAnimationFrame
,可以通过cancelAnimationFrame
取消 - visibility API,当页面隐藏时有些功能可以停下来
document.onvisibilitychange = function () {
if(document.hidden ){
console.log(Date.now());
}
}
- geolocation API
//watchPosition方法同getCurrentPosition,会跟踪用户位置
window.navigator.geolocation.getCurrentPosition(function success(position) {
console.log(`经度:${position.coords.latitude}`);
console.log(`纬度:${position.coords.longitude}`)
},function error(error) {
console.log(`Error code:${error.code}`);
console.log(`Error message:${error.message}`);
},{
enableHighAccuracy:false,//尽可能取最准确时间,不需要太准确的使用false,true会消耗更多电量以及时间
timeout:10000,//等待位置信息的最长时间
maximumAge:Infinity//上一次取得坐标信息的有效时间,,时间到则重新获取,不需要频繁更新设置为infinite
})
// clearWatch(watcherId)
附录
- 严格模式下
messsage = 123
创建变量为错误,delete 关键词不能删除变量,只能删除属性,非严格模式下可以删除window下创建的变量。 - 严格模式下apply、call的this始终是指定的值,非严格模式下null会被转化为window
- 严格模式下以0开始的八进制字面量为错误,现在使用
0b
、0o
、0x
表示二进制、八进制、十六进制
第一章 JavaScript简介
JavaScript实现组成:
- ECMAScript(核心)
- DOM(文档对象模型)
- BOM(浏览器对象模型)
第二章 在HTML中使用
- 可以添加
defer
关键字延迟执行,在文档被加载并完全解析后,类似与DOMContentLoaded
事件但是在DOMContentLoaded
事件之前,多个defer
脚本是按顺序调用的(但在现实中都不一定). - 可以添加
async
关键字异步加载,不会阻塞HTML的解析,会在onload
事件前,可能在DOMContentLoaded
前也可能在之后,多个异步不能保证顺序. - 在不支持脚本或禁用脚本时使用
no
使脚本平稳退化,内部可以使用HTML标签
onload事件在页面被完全加载完成后调用
DOMContentLoaded在HTML完全加载并解析后调用,不会等待样式表、图片等
第三章 基本概念
语法
- 始终在控制语句中使用代码块,即使只有一条控制语句(最佳实践)
- 八进制字面量在严格模式下是无效的
-
isNaN
会将值尝试转化为数值(调用Number转换)再进行判断 -
Number(null)
转换结果为0,Number(undefined)
转换结果为NaN,Number()
转换字符串类型复杂且不科学(比如Number("")
为0),使用parseInt()
转换字符串更好,也可以使用一元+操作符,效果与Number()
相同一元-与+规则相同,最后转换的数值添加- - 使用
toString
转换值为字符串,null和undefined没有这个方法(在不知道类型时可以使用String()
方法),转换数字类型时可以传入参数为转换的基数 -
propertyIsEnumerable
检查属性是否可迭代 - 在进行位操作时
NaN
和undefined
会被当做0,其他类型调用Number()
后进行位操作
按位操作符 | 解释 |
---|---|
| | 按位或 |
& | 按位与 |
~ | 按位取非 |
^ | 按位异或 |
<< | 左移(不会影响符号位),空位补0 |
>> | 有符号右移,空位以符号位填充 |
>>> | 无符号右移 |
无符号右移会将符号位看做数值,有符号位移操作忽略符号位
- 相等操作符:先转换后比较,全等操作符:仅比较不转换,null和undefined在比较前不进行转换.
语句
- 可以使用label语句配合break、continue退出循环
var num = 0;
outermost: for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
if (i == 5 && j == 5) {
break outermost;
}
num++;
}
}
alert(num);//55 退出整个循环
var num = 0;
outermost: for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
if (i == 5 && j == 5) {
console.log(num)
continue outermost;
}
num++;
}
}
alert(num); //95 强制退出内部循环,进行外部循环
- 使用
with
将代码专用域绑定到特定对象下,严格模式不允许使用with
语句,大量with
导致性能下降,不建议使用
var obj={a:1,b:2};
with(obj){
var getA=a;
var getB=b;
}
第四章 变量、作用域和内存问题
- 所有引用类型都是object的实例
- typeof 正则表达式为object
-
[1,2,]
在IE9以下为3项,最后一项为undefined,以逗号的个数判定 - 检测数组使用
Array.isArray()
,instanceof
的缺陷在于规定为一个全局环境,当使用框架时,框架A向框架B传递数组,两者的构造函数不同. - 调用数组的
toString()
实际上是对里边的每项使用toString
方法然后用逗号分割拼接,调用valueOf()
返回的还是数组. - 函数作用域:也可以说是Function中的[[scope]]属性,在函数定义时被创建,并且不会改变,闭包也是这个时候被创建,及[[scope]]属性中的closure属性,是包含对外部环境变量引用的对象。需要区分于作用域链,书中说的作用域链指包含活动对象的一条链,其配合上下文进行工作GPT改写。
第五章 引用类型
Date类型
通过特定日期创建Date对象需传入毫秒数,Date.parse()
和Date.UTC()
将特定日期解析为毫秒数
console.log(Date.parse("2019-11-24T18:09:00"))//根据日期解析为日期对象
console.log(new Date(Date.parse("2019-11-24T18:09:00")))
console.log(new Date("2019-11-24T18:12:00"))//直接传入内部会调用Date.parse()
console.log(Date.UTC(2019,10,24,18,14,00))//2019年11月
console.log(new Date(2019,10,24,18,14,00))//直接传入内部会调用Date.UTC()
上述方法返回的都是格林时间,如果要根据本地时间返回本地时间,有如下方法:
console.log(new Date('2020-04-18 17:50:00 GMT'))
console.log(new Date('2020-04-18 17:50:00 UTC'))
console.log(new Date(Date.UTC(2020,3,18,17,50,0)))
console.log(new Date().toLocaleString())
不同宿主环境返回值不同,最好还是自己解析把!!
RegExp类型
- 正则表达式
toString()
、toLocaleString()
返回对象字面量的字符串形式(String类型),valueOf()
返回正则本身(Object 类型) - exec方法返回第一个匹配项为模式匹配的内容,接下来为第一个捕获项、第二个捕获项。。。。,regexp实例中存放有
lastIndex
保存下一个匹配开始位置(在IE9以下即使为非全局模式下lastIndex
每次都会变化) - 命名捕获
const reg = /(?<year>\d{4})-(?<month>\d{2})/;
Function类型
- 函数表达式声明添加分号,就像普通声明一样(最佳实践),不推荐构造函数(Function)声明函数,会解析两次,一次解析ECMAScript,一次解析字符串,影响性能.
- 使用递归时,最好使用
arguments.callee
调用,避免函数名与执行函数的紧密耦合 - caller属性保存着调用当前函数的函数的引用,如果为window,返回null.严格模式下访问callee、caller均会报错,
function outer(){
console.log(arguments.callee.caller)//null
inner();
}
function inner(){
console.log(arguments.callee.caller);//[Function outer] 为了避免紧耦合使用arguments.callee
}
outer();
基本包装类型
- 基本类型调用方法步骤:
- 创建实例
- 调用方法
- 销毁实例
- Number类型方法:
-
toFixed()
传入参数,保留小数点后几位 -
toExponential()
传入参数,保留小数点后几位(以指数形式表示) -
toPrecision()
传入参数,代表数值表示的位数,会根据情况使用toFixed
和toExponential
- String类型
- substring()将所有负参数转化为0,substr()将第二个负参数转化为0
- split方法接收第二个参数指定数组大小,split可以使用正则
- replace方法函数形式第一个参数为匹配字符串、第二个后为捕获项,最后两个是匹配项位置和原始字符串(与exec类似,只是exec没有最后两个参数)
"agkg45gagn78agn5g".replace(/(\d)+/g,function(all,catch1,pos,str{
console.log(`all:${all},catch:${catch1},pos:${pos},str:${str}`)
})
all:45,catch:5,pos:4,str:agkg45gagn78agn5g
all:78,catch:8,pos:10,str:agkg45gagn78agn5g
all:5,catch:5,pos:15,str:agkg45gagn78agn5g
-
a.localeCompare(b)
a<b返回-1、 a===b返回0 、a>b返回1 -
String.fromCharCode()
返回字符编码转换后的字符串alert(String.fromCharCode(104, 101, 108, 108, 111)); //"hello"
单体内置对象
- 使用
encodeURI()
/decodeURI()
(对整个URI进行编码解码,对本身属于URI的不做操作)、encodeURIComponent
/decodeURLComponent
(对某部分进行解码,编码不管属不属于URI本身)进行解码和编码URI。需要注意使用哪个进行编码,只能使用对应的解码方法解码。 - 严格模式下,外部不能访问eval内部变量或者函数
- global对象作为ECMAScript的全局对象,没有提供直接访问它的接口,但是浏览器将global对象作为window对象的一部分加以实现。
第六章 面向对象的程序设计
理解对象
-
Object.defineProperty()
如果不指定enumerable(枚举)、configurable(可配置)、writable(可修改)默认值都是false - 可以使用
Object.defineProperties()
同时定义多个属性
var book = {};
Object.defineProperties(book, {
_year: { value: 2004 }, edition: { value: 1 },
year: {
get: function () {
return this._year;
},
set: function (newValue) {
if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
}
}
});
- 可以使用
Object.getOwnPropertyDeor(obj,property)
获取给定属性的描述 - 可以使用
obj.hasOwnProperty()
判断什么时候访问实例属性,什么时候访问原型属性,只有实例中存在对应的属性时才会返回true。如果想判断是否存在某个属性使用in
操作符,不管存在于原型还是实例都可以 - 重写constructor时记得将其定义为不可枚举
- 原型式继承
Object.create()
,可以不用事先预知子类构造函数,也存在共享父类引用的问题
function createObject(origin){
let superObject=function(){};
superObject.prototype=origin;
return new superObject();
}
- 组合继承的缺陷在于调用了两次父类实例,创建了两个父类属性,一个在原型上,一个在实例中
第一次:调用父类构造函数
第二次:将子类原型指向父类实例
寄生组合继承解决了这个问题,利用原型式继承的特点
function Person(name){
this.name=name;
}
function Child(name){
Person.call(this,name)
}
~function(){
let Super=Object.create(Person.prototype);
// 使用defineProperty定义的属性默认为不可枚举的(最佳实践)
Object.defineProperty(Super,constructor,{
value:Child,
// enumerable:false,
// configurable:false
})
Child.prototype=Super;
}()
console.log(new Child("forcehack"))
第七章 函数表达式
闭包
- IE9以前的DOM借鉴了COM,垃圾处处理机制使用引用计数,在处理DOM操作时不使用的DOM元素记得将其指向null
- 单例模式:只有一个实例的对象(字面量直接创建对象就是单例对象),在定义私有变量时可以使用
- 模块模式为单例创建私有变量和特权函数
var application=function createPrivate(){
var private=0;
function privateFunction(){return false};
return {
publicProperty:true,
publicFunction:function(){
private++;
privateFunction();
}
}
}();
第八章 BOM
window对象
- 使用var定义的window属性不允许使用delete删除,window定义的可以,因为var定义的window属性
configurable
不可配置 - 窗口位置
属性 | 解释 |
---|---|
screenLeft | 窗口相对于屏幕左边的位置(IE返回屏幕到窗口可见区域的距离,FF、Chrome返回到窗口的距离) |
screenTop | 窗口相对于屏幕上边的位置(IE返回屏幕到窗口可见区域的距离,FF、Chrome返回到窗口的距离) |
使用moveTo()
、moveBy()
移动窗口,可能被浏览器禁用(测试火狐、IE、谷歌最新版都不可用)
moveTo(x,y):移动到某个位置
moveBy(x,y):向右移动x,向上移动y
- 窗口大小
outerWidth
、outerHeight
:浏览器窗口大小innerWidth
、innerHeight
:视口(viewport)大小
IE9以前不支持,IE9以前以及其他浏览器可以通过dom获取视口大小
标准模式:document.documentElement.clientWidth
、document.documentElement.clientHeight
混杂模式:document.body.clientWidth
、document.body.clientHeight
通过resizeTo()
、resizeBy()
调整窗口大小(测试只有IE可用)
resizeTo(x,y):调整为宽x,高y的窗口
resizeBy(x,y):在原窗口的基础上,宽度调整x,高度调整y
- 最佳实践:setTimeout模拟setInterval实现
- 使用window.find()查找信息
第十章 DOM
IE9以下的DOM对象是以COM(组件对象模型)对象的形式创建的,所以存在IE中的DOM与原生JavaScript不一致的情况
节点层次
- 通过hasChildNodes()判断是否存在子节点比获取childNodes()判断length更有效
-
insertBefore
方法如果传递第二个参数为null,那么结果与appendChild
相同 -
normalize
方法用于标准化文本节点,有时候会创建空文本节点或者一个文本节点分成多个文本节点的情况,调用该方法可以处理这种情况(如果为空文本节点则删除,相邻的两个文本节点进行合并) -
document.domain
可以处理子域不同的跨域问题,document.referrer
指向来源页面的URL,如果域名一开始是松散的就不能在将其设置为紧绷的。 - IE9以下cloneNode会克隆事件
- IE9以下不区分ID大小写
- 通过getElementsByTagName()获取的HTMLCollection可以通过namedItem()通过元素name获取元素,也可以通过方括号获取
- IE中可以通过element.name、element.getAttribute()获取属性,其他浏览器只有基本属性可以element.name,推荐基本特性使用属性的方式获取、设置,自定义特性使用getAttribute/setAttribute
第十一章 DOM扩展
HTML5
-
document.compatMode
标准模式CSS1Compat
,混杂模式BackCompat
- outerHTML返回节点以及本身的HTML,写模式下进行替换,包括自身
-
insertAdjacentHTML
,插入位置为beforebegin
、afterbegin
、beforeend
、afterend
- 在进行元素替换时,比如
innerHTML
、outerHTML
、insertAdjacentHTML
,元素与事件处理程序之间的捆绑关系并不会一并删除,会一直保存在内存中,所以在使用这些方法之前最好先接触元素与事件之间的关系。 -
scrollIntoView
可以控制元素滚动到可视区域与顶部平齐或者尽量铺满可视区域(底部与可视区域底部平齐) ,参数为true或者不进行传递时效果为第一种,参数为false时效果为第二种 - 使用
element.contains
判断是否包含某子元素
第十二章 DOM2和DOM3
样式
- 通过JavaScript指定float时最好使用
cssFloat
,因为float是JavaScript关键字,IE11已经支持,低版本IE使用styleFloat
- style可以通过
getPropertyValue
获取属性,通过removeProperty()
移除样式属性(恢复默认值) - 通过
cssText
指定css会重写内联样式的值 - 通过
document.defaultView.getComputedStyle()
可以获取计算后属性,第一个参数为元素,第二个为伪元素字符串,如:after
如果不需要伪元素信息可以指定为null。defaultView
指向窗口 - 可以通过
document.styleSheets
获取样式表信息,通过sheet.insertRule('body{background:red}',0)
方法添加规则,第一个参数为规则字符串,第二个为插入位置。通过sheet.removeRule(0)
删除规则。
遍历
-
document.createNodeIterator(root,whatToShow,filter,false)
创建结点迭代器,使用深度优先遍历,whatToShow值在NodeFilter类型中定义NodeFilter.SHOW_ALL
、NodeFilter.SHOW_ELEMENT
、NodeFilter.SHOW_TEXT
,第三个参数用于指定自定义的NodeFilter对象,如果应该访问该对象,该方法返回NodeFilter.FILTER_ACCEPT
、NodeFilter.FILTER_SKIP
document.createNodeIterator(box,NodeFilter.SHOW_ELEMENT,function(node){
return node.tagname.toLocaleLowerCase()==='p'?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP;
},false);
通过nextNode()
和previousNode()
对迭代器进行访问,第一次调用nextNode()
返回root根节点。
- 也可以通过
document.createTreeWalker
进行遍历,与createNodeIterator
类似,但是比createNodeIterator
更方便,filter方法新增NodeFilter.FILTER_REJECT
会跳过当前节点以及其整个子树,除了nextNode
和previousNode
两个方法外,还提供了用于在不同方向上遍历DOM结构的方法
parentNode
firstChild
lastChild
nextSibling
previousSibling
范围
- 使用
document.createRange()
创建range对象,通过range.setStart(container,index)
、range.setEnd(container,index)
确定范围
操作方法:
-
range.deleteContents()
删除文档碎片 -
range,extractContents()
与deleteContents
类似,区别在于会返回删除的文档碎片 -
range.cloneContents()
与extractContents
类似,但是只是返回副本,不会删除 -
range.insertNode(node)
在范围前插入节点 -
range.surroundContents(element)
节点包围范围 -
range.collapse()
折叠范围,传递true折叠到起点,传递false折叠到终点,通过range.collapsed
查看是否已经折叠 -
range.compareBoundaryPoints()
比较范围 -
range.cloneRange()
克隆范围 -
range.detach()
将范围从文档中分离,在使用range = null
,以便垃圾回收机制进行回收
- IE8之前需要不支持
document.createRange()
,但支持类似的方法
第十三章 事件
事件类型
- 、link、img均存在load事件,link和必须添加到文档中才开始下载,而img指定src就会开始下载0
- focus和blur事件不会冒泡(但是仍然可以在捕获阶段监听),focusin和focusout可以进行冒泡
- 事件对象中存在
shiftKey
、altKey
、ctrlKey
、metaKey
,如果有相应的键被按下,相应的值为true,否则为false - 对于mouseover和mouseout事件,
relatedTarget
属性保存着相关元素,<IE9需要做兼容 -
event.detail
属性保存着在同一位置的点击次数 - 复合事件用以处理输入法编辑器(输入键盘上找不到的字符),
compositionstart
、compositionupdate
、compositionend
-
HTML5事件
-
contextmenu
右键上下文菜单(window)或者ctrl+单机(mac)触发 -
beforeunload
页面将要卸载时调用,显示消息event.returnValue=message;return message //并将消息在函数中返回
(许多浏览器会忽略该事件) -
DomContentLoaded
形成完整的DOM树之后触发 -
hashchange
,URL参数发生变化时调用
-
模拟事件
- 模拟事件通过
document.createEvent()
创建事件,也可以创建自定义事件—p405
const app = document.querySelector('#app');
app.addEventListener('click',function(){
alert(123);
})
const event = document.createEvent('MouseEvents');
event.initEvent('click',true,true,document.defaultView,0,0,0,0,0,false,false,false,false,0,null);
app.dispatchEvent(event);
第十四章 表单脚本
表单的基础知识
- 避免重复提交表单的方法
- 第一次提交表单后禁用提交按钮
- 利用onsubmit事件处理程序取消后续的表单提交操作
- 表单元素存在elements属性,保存着所有表单元素的集合
- 可以添加autofocus
文本框脚本(IE8以下基本都需要做兼容)
- input元素size特性可以指定文本框显示大小,maxlength特性可以指定最大字符数,初始值使用value标记,textarea元素初始值写在标签之间
- 可以调用
select
方法选择文本,selectionStart
、selectionEnd
保存着选择文本的位置 - 使用
setSelectionRange
方法可以进行部分文本选择,先要将焦点设置到文本框 - 剪切板事件
beforecopy
、copy
、beforecut``cut
、beforepaste
、paste
,event对象中存在clipboardData
,存在方法setData
、getData
、clearData
获取数据 - 文本框可以使用
pattern
特性指定匹配,添加required
变成必填字段 - 可以对表单使用
checkValidity
方法检测整个表单是否有效,也可以对单个字段使用 - 通过
novalidate
属性可以告诉表单不进行验证 - 为按钮添加
formnovalidate
则不进行验证提交表单
选择框脚本
- select元素可以使用
add(newoption,reloption)
添加新option -
remove(index)
移除option -
options
保存有所有option,推荐使用上述获取元素,尽量少使用DOM - 可以使用
Option
构造函数创建option选项,new Option('option text','option value')
富文本编辑–p439
- 通过嵌入空的html的iframe,并将空文档的
designMode='on'
。或者设置元素contenteditable
达到可编辑的目的 - 利用
document.execCommand
执行命令,实现富文本
第十五章 使用canvas绘图
2D上下文–p446
-
getContext('2d')
获取上下文,toDataURL('image/png')
canvas元素上绘制的图像导出(是canvas上的方法,不是上下文的)。 -
fillStyle
和strokeStyle
设置填充颜色和描边颜色 -
fillRect(x,y,width,height)
和strokeRect(x,y,width,height)
画矩形 ,使用clearRect(x,y,width,height)
清除矩形区域 - 绘制路径前需要使用
beginPath()
- 使用
fillText
和strokeText
绘制文本 - 可以使用
drawImage
绘制图像 - 也可以对绘制图形设置渐变和阴影
第十六章 HTML5脚本编程
原生拖放
- drag事件,源阶段
dragstart
、drag
、dragend
,目标阶段有dragenter
、dragover
、dragleave
或者drop
事件,阻止dragenter
、dragover
、drop
默认行为可以将设置目标为可放置目标 - 通过事件对象的
event.dataTransfer.setData('text/plain','这是传送的消息')
和event.dataTransfer.getData('text/plain')
可以达到传送消息的目的
const source = document.querySelector('#drag-source');
const target = document.querySelector('#drag-target');
source.addEventListener('dragstart',function(event){
event.dataTransfer.setData('text/plain','这是传送的消息');
})
target.addEventListener('dragenter',function(event){
event.preventDefault();
})
target.addEventListener('dragover',function(event){
event.preventDefault();
})
target.addEventListener('drop',function(event){
alert(event.dataTransfer.getData('text/plain'));
})
- 默认只有图像、链接和文本可拖动,元素可以通过
draggable
属性设置是否拖动
媒体元素
- 为媒体元素poster特性指定url可以用于加载内容期间显示图像
- timeupdate事件是currentTime被意外改变时触发,所以改变currentTime显示值,最好使用定时器
历史状态
- 可以通过hashchange事件监听URL的改变,也可以通过
window.history.pushState({name:'forcehack'},'page title','page.html')
达到管理状态的目的,浏览器不会像服务器发送请求(不卸载当前页面修改历史栈)
第二十章 JSON
- JSON数据会跳过值为undefined的数据
-
JSON.stringfy()
第二个参数为过滤器,如果为数组形式,则只返回数组中对应的键的数据,如果为函数形式,函数接收键和值两个参数,返回值,返回undefined则跳过。第三个参数为表示缩进,如果为数字类型则表示缩进多少,如果为字符串,则使用字符串中的值标记缩进 - 如果对象存在
toJSON
方法,那么JSON.stringfy
调用toJSON
方法 -
JSON.parse
也可以接收第二个参数为一个函数,同样接收键值对,返回值,返回undefined进行删除
第二十一章 Ajax与Comet–P578
- FormData使用
append(key,value)
传入数据,FormData也可以直接传入表单元素new FormData(document.forms[0])
- 可以使用
overrideMimeType(text/xml)
重写响应类别,强迫xhr对象将响应当做xml处理 - xhr支持进度事件
progress
、load
,progress
事件可以用于处理进度信息(存储在事件对象中)。
const xhr = new XMLHttpRequest();
xhr.onload = function(){
console.log(event);
console.log(JSON.parse(xhr.response));
};
xhr.open('GET','https://jsonplaceholder.typicode.com/todos',true);
xhr.send(null);
-
XMLHTTPRequest
默认实现了对CROS的支持,只要在请求时传入绝对URL即可,限制在于
- 不能使用
setRequestHeader
创建请求头 - 不能发送和接受cookie
- 不能使用
getAllResponseHeaders()
获取响应头信息(始终为空字符串)
为了区分同源还是跨源,则在本地使用时最好使用相对URL,跨源使用绝对URL,实现原理在于发送请求时,浏览器会自动发送一个Preflighted Request携带Access-Control-Request-Headers
、Access-Control-Request-Method
、Origin
CROS需要的头部信息,该请求使用OPTIONS方法,代价只是第一次发送时需要多发送一次HTTP请求
- Comet:一种服务器向页面推送数据的技术,实现方式长轮询或者HTTP流
短轮询:页面定时向服务器发送请求,看看是否有数据更新(利用setTimeout和ajax即可实现)
长轮询:页面向服务器发送请求,服务器保持连接,有数据了向页面发送数据,浏览器关闭连接,同时向服务器继续发起新请求,在页面存在期间持续不断
HTTP流:只创建一次HTTP连接,服务保持连接,周期性的向浏览器发送请求,xhr通过readystate事件监听readystate是否为3
服务器发送事件API(SSE)支持短轮询、长轮询和HTTP流,并且能在断开连接时自动确定何时连接,EventSource有一个readystate属性,0表示正在连接到服务器,1表示打开了连接,2表示关闭了连接
const source = new EventSource('myevents,php');//URL必须同源
同时有3个事件API,open
、message
、error
,默认是会保持连接,也可以说SSE适合长轮询和HTTP流,如果断开连接可以调用source,close()
WebSocket
两者选择:由于webSocket不同于HTTP,有自身的协议,所以现有服务器不能用于webSocket,是否有能力建立和维护webSocket服务器,考虑是否真的需要双向通信,如果只需读取服务器数据,SSE更好(组合XHR和SSE也能实现双向通信)
第二十二章 高级技巧
-
Object.preventExtensions()
将对象设置为防篡改对象,通过Object.isExtensible()
检测是否可扩展。但是可以修改已有属性,也可以删除 -
Object.seal()
密封对象,对象不可扩展,不可删除,通过Object.isSealed()
检测是否被密封 -
Object,freeze()
冻结对象,不可扩展,不可删除,不可修改,使用Object.isFrozen
检测是否被冻结0
第二十三章 离线应用与客户端存储—P628
-
navigator,onLine
检测是否在线同时提供online
、offline
两个事件监听网络 - appcache是从浏览器缓存中分出来的一块缓存区,如果想在其中保存数据,可以使用描述文件(mainfest file),列出需要下载和缓存的资源
CACHE MAINFEST
#Comment
file.js
file.css
需要与页面关联可以使用在html元素中指定mainfest属性<html mainfest = '/offline.mainfest'>
,相应的API查看缓存正在做什么是applicationCache
对象,可以通过applicationCache.update()
触发检查更新
- 有时为了绕开浏览器单域名下对cookie个数的限制,可以使用子cookie,如
name=name1=value1&name2=value2
//name后边内容作为name的值出现,算作一个cookie,即子cookie的概念
第二十四章 最佳实践—P668
- 使用减值迭代
- 使用后测试循环
- 展开循环(Duff技术)
- switch语句更快
- 使用innerHTML,innerHTML会在后台建立DOM调用创建DOM,不是通过JavaScript,更快
- 注意HTMLCollection
getElementsByTagName
attributes
childNodes
-
document.forms
、document.images
等
- HTTP压缩,代码压缩(YUI)
第二十五章 新兴API
- 在下一次页面重绘前调用
requestAnimationFrame
,可以通过cancelAnimationFrame
取消 - visibility API,当页面隐藏时有些功能可以停下来
document.onvisibilitychange = function () {
if(document.hidden ){
console.log(Date.now());
}
}
- geolocation API
//watchPosition方法同getCurrentPosition,会跟踪用户位置
window.navigator.geolocation.getCurrentPosition(function success(position) {
console.log(`经度:${position.coords.latitude}`);
console.log(`纬度:${position.coords.longitude}`)
},function error(error) {
console.log(`Error code:${error.code}`);
console.log(`Error message:${error.message}`);
},{
enableHighAccuracy:false,//尽可能取最准确时间,不需要太准确的使用false,true会消耗更多电量以及时间
timeout:10000,//等待位置信息的最长时间
maximumAge:Infinity//上一次取得坐标信息的有效时间,,时间到则重新获取,不需要频繁更新设置为infinite
})
// clearWatch(watcherId)
附录
- 严格模式下
messsage = 123
创建变量为错误,delete 关键词不能删除变量,只能删除属性,非严格模式下可以删除window下创建的变量。 - 严格模式下apply、call的this始终是指定的值,非严格模式下null会被转化为window
- 严格模式下以0开始的八进制字面量为错误,现在使用
0b
、0o
、0x
表示二进制、八进制、十六进制