JS 学习笔记
解释型语言
(区别于编译,不报错,不识别不显示) 编译执行快,不跨平台,解释性慢但跨平台
JS php python等均解释性 java特殊,先编译,后jvm解释
单线程
同时只能做一件事 轮转时间片
ECMA标注
微软的JScript,为了统一标准都兼容ECMA标准,因此也称ECMAScript(ECMA 欧洲计算机标准)
三大部分
ECMAScript DOM BOM(后两个是浏览器厂商标准,所以有兼容性问题)
ECMAScript
script可以写在head或body里,也可以引入外部js文件
中断
执行js、下载js会阻断其他一切任务,直到js任务执行完,所以js写在最下面最好,否则因中断容易失效
WEB标准
结构样式行为相分离
js语法
批量声明 var a,b,c=1,d; 命名规则同Java
数据类型
number数字类型 string字符串数据 布尔类型 undefined类型 null(原始值) 引用型(数组 对象 函数)
var是弱数据类型,解释型语言特色
栈内存指针被删除并且栈内存被占满时会被覆盖
语法规则
1.每个语句后面加分号
2.js错误[语法解析错误 逻辑错误]会引起全部代码运行,但不会影响其他代码块的执行
3.书写格式要规范,“= + / -”两边都应该有空格
算术运算符
只有undefined null NaN "" 0 FALSE 才会被认为是false
短路的逻辑写法
传回去的不是真正的boolean值,而是传递的决定最终值的表达式本身
if的第二种写法 1>2 && console.write(a);
IE浏览器的兼容示例 div.onclick=funtion(e){var event = e || window.event; }(ie的e不存事件和元素)
!运算符是先把表达式变成布尔值然后取反
流程语句
判断 循环 无限循环(一直转圈 程序会先试图运行下)
数组
多种类型可以存在一个数组内
稀松数组:字面量是定义时的长度
js中数组是基于对象实现的
push 一个多个都行 pop取出最后一个 shift取出第一个 unshift往前放 shift从前面开始取
splice(i,j,k,…)第i开始切j位其他参数补原数组中 reverse 逆序
不对原数组做修改:
sort:对数组排序 sort(function(a,b){冒泡比较法,自己穿策略,返回负数,前者在前。返回正数,后者在前})
var arr2=arr.concat(arr1)连接数组
slice(i,j)从第i位截到第j位 注,-x是从倒数x位开始
arr.join(xx) 数组元素以xx为链子连字符串,默认是个逗号
type of
区分数据类型 number string boolean function object undefined
类型转换
显式
Number(); parseInt(demo,redix); redix(代表进制,以目标进制为准转换成10进制) int会从数字位开始看到
非数字位为止 num.toFixed(3);(保留三位有效数字,四舍五入)
parseFload 与int相似 无radix toString() undefined和null不能使用 demo.toString(8) demo会变成8进制
String(mix) Boolean() isNaN()会把结果先Number()再比较 + a - a a++ a-- 都会强制变成数字
+两边有一个字符串就会变成字符串
undefined == null(true) NaN == NaN(false) === 不发生类型转换的绝对等于 !==同理
当且仅当typeof(a)的时候不定义也不报错 其他情况下不定义会报错 typeof(typeof(a))不报错而且是字符串
因为typeof返回值必是字符串
隐式
函数
声明
function xxx(){ }
表达式
命名函数表达式function xxx(){ }
匿名函数表达式function (){ } 也叫函数表达式
arguments = [,,]; 真实参数列,即没有
库
window.promt('input') string[i]写法
作用域
内层可以用外层,外能不能访问内层 全局 局部变量
js执行三部曲
语法分析,预编译,解释执行
预编译:函数声明整体提升(编译时被放到逻辑最上面)
变量提升(变量的声明提到最前面)
预编译前奏
1.imply global 暗示全局变量,任何变量未经声明就赋值,就归全局对象所有(window)var a=b=123;
2.一切声明的全局变量都归window所有 ==>window就是全局的域
预编译
发生在函数执行前一刻
1.创建AO对象(执行期上下文 Activation Object) AO{}
2.找函数里面的形参和变量声明,将形参的名和变量得名当作AO的属性挂上去(undefined)
3.将实参和形参的值相统一
4.在函数体找函数的函数声明(表达式不行),值赋予函数体
全局预编译
没有实参同步,其他一致
if中,不允许定义函数
false与数字相加 隐式类型转换为0
加减比门高
立即执行函数
作用域
[[scope]]
每个Js函数都是一个对象,对象中有些属性我们可以访问,有些不可以,这些属性仅供JS引擎存取,
[[scope]]就是其中一个。
[[scope]]就是我们所说的作用域,其中存储了运行期上下文的集合。
每个执行期上下文都是独一无二的,各自单独生成,每调用一次生成一次,用完被销毁
作用域链
[[scope]]里面存储的上下文集合,成链式链接,我们称其为作用域链。
闭包
闭包会导致多个执行函数共用一个共有变量,非特殊需要情况下,不使用闭包(导致原有作用域链不释放)
立即执行函数
(fn(){}) 会立刻执行,执行完再也找不到了 相比于(fn(){})() w3c标准更提倡(fn(){}())
注意批量子函数定义完的公共变量,尤其注意循环
原型
定义了function的一个属性,定义了构造函数制造出的对象的公共祖先,属性或方法可以继承
可以提取共有属性
查看原型: .__proto__ __proto__:Person.prototype
方法形式定义prototype时候记得带上Constroter:ClassName
js中不是所有对象都继承自Object 有用Object.Creat(null);的方法创建的 Creat(Object)
原型只有在创建对象之前改才有用
先创建变量再修改原型就没用了
圣杯模式
雅虎的闭包圣杯模式
var inherit = (function(){ var F = function(){}; return function(Target, Origin){ F.prototype = Origin.prototype; Target.prototype = new F(); Target.prototype.constructor = Target; Target.prototype.uber = Origin.prototype; } }());
链式调用以及属性名拼接
取对象属性只能方括号,会自动把x点变成x['']
hasOwnProperty() 是否有自己的原型属性
a instance of b 看a的原型链上是否有b
arguments.callee是函数对自己的引用
函数.caller返回函数执行的环境,全局调用返null
浅度克隆
引用值直接引用
深度克隆
引用值也完全克隆出一份新的
instance of和constructor存在父子域会失灵
Object.paorotype.toString.call(target)
call
call(a,b,c); 执行函数,第一位改变this的指向,后面开始是参数列表
call()空执行,主体的this是window
call和apply 作用:改变this指向,参数列表不一样
this
1.预编译AO里面的this指window,2.全局作用域里this指window,3.call apply可以改变函数运行时this指向
4.obj.func();func里面的this指向obj
top是window的一个属性,是顶级父级窗口的【<iframe src=></>】
window.name是一个传递数据的东西,不清缓存就会一直存在
三目运算符
1 > 2 ? 2 : 3 等价于 if 1>2 则结果为2,否则结果为3
数组元素换成对象属性去重,要赋给一个确认值,否则表示否定的值会无法去重,如0、undefind、false等
深度遍历克隆
var target = target || {} (如果传进来空对象就用传的,没传就用自己建的空对象)
类数组
典型如arguments,看起来像个数组,但push会报错
类型数组也叫对象数组,可以当数组操作,也可以用数组的方法,一旦给对象赋予Array的原型链方法,
展示就会变成数组形式,辨识以length为标记,改了会乱
既能当数组也能当对象用
try catch
同后端,执行到出错的行为止 同样有finally
Error.name的六种值对应信息
1.EvalError: eval()的使用和定义不一致
2.RangeError: 数值越界
3.ReferenceError: 非法或不能识别的引用数值(没定义就用了)
4.SyntaxError: 发生语法解析错误
5.TypeError: 操作数类型错误
6.URIError: URI处理函数使用不当(Ajax)
ECMAScript
ES1.0--6.0
ES3.0--5.0
ES6目前只有小范围使用
三四年前ES3.0 两三年前ES5.0 现在基本默认ES3.0和5.0的混合版本,冲突以ES3为准。即ES5不标准模式
ES5严格模式
有冲突的东西
"use strict" 加到前面,后面都会冲突取5 写在函数里面第一行,函数自己用 写全局就在全局最上
有需求一般写在局部,避免影响未知代码块 这种启动方式不会导致低版本报错 兼容性
如arguments.callee();(caller callee都不能用)
with(b)可以改变作用域链,提供了一个执行期上下文,强行安装b的作用域链到顶端,配合命名空间很好用
{with很费性能,所以一般不用,干脆很多公司就直接开strict模式}
变量赋值前必须声明
局部this 必须被赋值,Pesrson.call(null/undefind)赋值什么就是什么 ***要再看
拒绝重复属性和参数
DOM
系统提供的一系列方法,可以直接操作HTML和XML,通过HTML间接改CSS
是一个工具,操作文档 document object model 浏览器厂商制定,用来对HTML和XML进行操作的标准编程接口
document.getElementById();
xxxsByTagName();
xxxsByClassName();用得少
xxxsByname(); 针对表单 img iframe等
querySelector xxAll ie7及以下不能 非实时
xxxsByTagName().length; .length循环遍历效率很低(每次都要去实时索引元素,应该以变量记下长度)
节点
遍历节点树
x.getPraentNode() //最顶端的parent是#document
x.getChildNodes()
node.leftChild()
.lastChild()
nextSlibing
previousSlibing 前后兄弟节点
类型
不只有dom结构是节点
1 元素节点
2 属性节点
3 文本节点
8 注释节点
9 document
11 DocumentFragment
.nodeType()获取节点类型
文本节点连起来算一个
四个属性
nodeName 标签名,大写形式表示,只读
nodeValue Text节点或Comment节点的文本内容,可读写
nodeType 类型,只读
attributes Element节点属性合集,
.artributes,可赋值,可操作dom属性
node.hasChildNodes
遍历元素节点树 (IE9以下不兼容,9相当于换了个内核)
方法同节点树,Node变Element
很多不兼容(ie9以下)
.childen(值返回当前元素的子节点)都兼容
DOM结构树
各种DOM结构存在继承关系...**************
DOM基本操作
元素
操作標簽
增
document.createElement(); 创建元素节点
document.createTextNode(); 创建文本节点
document.createComment(); 创建注释节点
document.createDocumentFragment();
插
document.appendChild(); 把标签插在最后,可传选中的标签进去,可实现剪切
document.insertBefore(a,b); 在b之前插入a,也可以实现剪切
删
parent.removeChild(); 删掉一个儿子
child.remove(); 把自己删了
替换
parent.replaceChild(new,origin); 用新的替换原来的,会返回旧的
属性
Element一些属性
innerHTML
可读写,是字符串格式,可直接加号拼接,甚至直接写HTML文档
innerText(火狐不兼容)/textContext(老版本IE不好使)
轻易不赋值,会覆盖
Element一些方法
ele.setAttribute(); 给标签添加一些行间属性 性能很高,批量改,很方便
ele.getAttribute(); 一个小用处,可以监控网站使用次数,行间数据当存储空间
类与方法
静态类
JS是C语言写的
DATE
Date.getFullYear(); 发展史,getyear为什么错
纪元时间 1970 1 1 0 0 0
getTime 算执行时间 以后一般会在请求尾部拼接一个,作为唯一标识避免浏览器用缓存敷衍
Date.parse() 时间时间戳化 x.setXXX 改变时间戳值 常用于做闹钟秒杀
定时器
var x = setInterval(fn(),int); 每隔int毫秒执行fn
clearInterval(x); 用法类似于循环的break
setTimeOut(); 类似,是int毫秒后执行fn,也有clear
定时器计时器的fn写成字符串类型的代码也ok,里面fn的this都是window int是写死的无法重新赋值
BOM基本操作
滚动条
返回滚动条在哪
window.pageYOffSet() 查看滚动条拉动位置
window.pageXOffSet() 查看条X轴拉动位置
兼容性混乱
document.body/documentElement.scrollLeft/scrollTop 用的时候取两个值相加,同时只能存在一个有值
架构
一般都会封装好兼容性方法,求滚动条滚动离getScrollOffset()
视窗
可视区窗口
怪异模式
开启方式
不写HTML5头标签 <!DOCUMENT html>
查看方式
document.copatModel "BackCompat" 标准模式兼容关闭 "CSS1Compat" 标准模式兼容开启
查看视窗尺寸
window.innerHeight IE8及以下不兼容
document.documentElement.clientWidth/clientHeight标准模式下任意浏览器都兼容
document.body.clientWidth/clientHeight 适用于怪异模式下的浏览器
架构
封装兼容性方法,返回浏览器尺寸getViewportOffset()
元素
查看元素几何尺寸坐标等
document.getBoundingClientRect(); 兼容性很好 返回一个对象,含left、top、rignt、bottom
分别代表左上角x y左边和右下角的坐标
height和width属性老版本ID未实现
返回的结果不是实时的,类似于快照
查看元素尺寸2
dom.offsetWidth(); dom.offsetHidth(); dom.offsetLeft(); dom.offsetTop(); (left top 是相对于父级)
dom.offsetParent();返回最近的有定义的父级
滚动条滚动
window.scroll(x,y);滚动条定位到那个点 window.scrollTo(x,y);滚动条定位到那个点
window.scrollBy(x,y);滚动条向那走那么远
一般用于在哪展开或加载更多项 关闭的时候回到哪去
可实现自动阅读等
操作CSS
dom.style.color
float这个属性最好前面加css单词
复合属性必须拆解,组合单词小驼峰
写入的值必须是字符串
window.getComputedStyle(dom,null); //第二个参数是伪类参数,可用于获取样式
记录元素style的最终展示值
计算样式只读,是绝对值(真实值,相对值会被转换)
dom.currentStyle
也是获取,相对值(写的是什么就是什么,不转换) IE独有的属性
功能对应几个状态位
最好还是写在.class上而不是伪类上,伪类原生太难操作
轮播图
list 首尾连起,浮动就横过来了 四张图轮播,用五张图,第一张和最后一张都是第一张
事件
事件和反馈
dom.onclick = fn(){};
点击触发 兼容性很好 只能绑定一个 本质上还是属性赋值 基本等于写在行间
叫做句柄的绑定方式
obj.addEventListener(type,fn,false);
IE9以下不兼容,W3C标准
可为一个事件绑定多个处理器
obj.attachEvent('on'+type,fn);
IE独有,一个事件那可以绑定多个处理程序
但凡绑定事件遇到了循环,一定要小心闭包
解除事件处理函数
执行完如果想销毁可直接重新赋值为空
ele.onclick = false/null;
ele.removeEventListener(type,fn,false);
ele.detachEvent('on'+type,fn);
注:若绑定匿名函数则无法解除
架构
事件绑定函数,兼容性封装
事件处理模型
事件冒泡
结构上(非视觉上)嵌套关系的元素,会存在事件冒泡的功能,即同一事件,自子元素冒泡向父元素(自
-底向上)
事件捕获
结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,自父元素捕获向子元素
-(事件源元素)
IE没有捕获事件
触发顺序
先捕获,后冒泡
不冒泡事件
focus,blur,change,submit,reset,select等事件不冒泡
好处/坏处
即便不绑定事件,因为冒泡也会自然有事件
有时候会误触发
阻止冒泡
函数内的参数e 或者$event
event.stopPropagation(); W3C标准,但不支持IE3及以下
event.cancelBubble = true; IE独有
封装取消冒泡的函数stopBubble(event)
阻止默认事件
默认事件:表单提交,a标签跳转,右键菜单等
1.return false;以对象属性的方式注册的事件才生效
2.event.preventDefault(); W3C标准,IE9以下不兼容
3.event.returnValue = false; 兼容IE
封装组织默认事件的函数 cancleHanler(event);
行间JS写 <a href = "javaScript:void(false/null)"> 也相当于直接返回false 也能阻断
获取事件对象
var event = e || window.event;
var target = event.target || event.srcElement;
事件委托
子元素太多的时候直接把事件绑定给父级
优点
1.性能:不需要循环所有元素一个个绑定事件
2.灵活:当有新的子元素时不需要重新绑定事件
事件捕获与操作
仅IE好使,div.setCapture releaseCapture 捕获全部事件给自己 释放这种状态
鼠标事件
onmouseover 鼠标闯入区域
onmouseout 离开
html5叫onmouseenter 和xxleave
检测鼠标左右键 up down方法的e有一个属性button 左0右2滚轮1
click不能监听右键 DOM3标准规定
移动端 touchStart touchMove touchEnd
键盘类事件
keydown keyup keypress
按住不放反复出前俩
keydown响应任意按键 keypress只响应字符
keypress可返回ascll码,可转换为字符 e.charcode keydown检测字符类不准,不区分大小写
oninput onchange
窗体操作类
onscroll滚动条
load load在全部页面加载完毕后开始加载调函数dom的资源
load本身吃资源费时间,不好。但也有用处,可提醒整个页面加载完毕了可以用了
浏览器加载
下载页面 请求回来后
并行生成domTree 和 cssTree
两棵树完成后叠在一起形成渲染树renderTree
解析完有附属资源的标签会先放到树上,然后开一个异步线程去下载资源 下载完拼到目标
轮播图
list 首尾连起,浮动就横过来了 四张图轮播,用五张图,第一张和最后一张都是第一张
任务冲突
重读调用
上锁
自定义一个boolean
运动
本质
单位时间怎样改变多少距离(操作位置或形状或透明度属性)
知识点
如果设置值不足1px,像素位会直接被干掉
.opacaty透明度
Math.ciel向上取整 Math.floor向下取整
基本都是setInterval +clear
根据时间差,操作top left 尺寸 透明属性
setInterval -- clear + style.left = .offsetLeft 外带自定义变量和游标 Math.abs()
如果运动导致视窗越界,会出滚动条,所以需要在越界的时候赋值,使它不越界不触发闪屏
Json
一种数据传输的格式(以对象为模板,本质上就是对象,但用途有区别,对象就是本地用的,json是用来传输的)
JSON.parse(); string-->json
JSON.stringify(); json---->string
与对象区别:1.属性名必须加双引号 2.字符串不能换行
异步加载JS
script加载JS会阻塞页面
有时网不卡页面卡,页面啥都没,是js文件太多了
JS阻断页面的原因是 JS致力于修改页面结构,所以要先锁死页面
有些工具方法需要按需加载,用到在加载,不用不加载
三种方案
1.js标签加 defer = 'defer' (也可以只写名字) 只有IE能用
defer会等待js解析完毕才会执行
2.asycn 异步加载外部js文件,IE9以上才能用
W3C标准
前俩不能一块用,会覆盖
第二种不能要的时候随时加载完成,如果没加载完就调用会报错
3.创建script,插入到DOM中,加载完毕后callBack
var = doc.createElement('script') script.src = url doc.readyState loading complete loaded等
doc.baby.appendChild(scipt) scrict.ready loading script.onload = function(){ chrome opera test();}
配合onload一起使用,可以避免没加载完成导致的报错
IE没有,但是有script.readyState 内有loading complete loaded等 但下载完readystate会立刻变
如果传输很快,反而会在尚未执行判时候出问题,所以事件先绑定后监听
callback 回调函数
或者把传进去的函数包在一个匿名函数声明中
JS加载时间线
1、创建Document对象,开始解析web页面。解析HTML元素和他们的文本内容后添加Element对象和Text节点
到文档中。这个阶段document.readyState = 'loading'。
2、遇到link外部css,创建线程加载,并继续解析文档。
3、遇到script外部js,并且没有设置async、defer,浏览器加载,并阻塞,等待js加载完成并执行该脚本,然后
继续解析文档。
4、遇到script外部js,并且设置有async、defer,浏览器创建线程加载,并继续解析文档。对于async属性的脚
本,脚本加载完成后立即执行。(异步禁止使用document.write()一般也没人写,会清除文档流 也就是清除
源码)
5、遇到img等,先正常解析dom结构,然后浏览器异步加载src,并继续解析文档。
6、当文档解析完成,document.readyState = 'interactive'。
7、文档解析完成后,所有设置有defer的脚本会按照顺序执行。(注意与async的不同,但同样禁止使用
document.write());
8、document对象触发DOMContentLoaded事件,这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶
段。
9、当所有async的脚本加载完成并执行后、img等加载完成后,document.readyState = 'complete',window对
象触发load事件。
10、从此,以异步响应方式处理用户输入、网络事件等。
正则
正则表达式
作用
匹配特殊字符或者有特殊搭配原则的字符的最佳选择
其他
HTML中元素加了ID 可以直接在js中免声明取值直接使用,ID在HTML中最好不重复,
否则虽然不报错,但出了bug玩一天
用法
创建
创建字面量 var reg = /parttern/;
创建对象 var reg = new RegExp('pattern',i);
使用
var result = reg.exec(str);
reg.test(str); //返回
reg.match(str);//返回匹配到的字串的数组 -g全部,否则只返回第一个
用法
属性:
i(忽略大小写) g(全局匹配) m(多行匹配)
转义字符
(\*->和特殊字符组合有特殊功能)
(和极特殊字符组合如转义字符,可输出极特殊字符本身)
/n 回车
方括号
[]: 匹配某字符,如[abc] [a-z] [a-z]i (a-z忽略大小写)
元字符
. 查找单个字符,除了换行和行结束
\w 查找单词字符
\W 查找非单词字符
\d 查找数字
\D 查找非数字字符
\s 查找空白
\S 非空白
\b 单词边界 如/\babc/ 代表匹配abc的左侧边界 如eabc左侧边界为e 注:开头什么都没有也是边界
\0 查找NUL字符
\n \f \
[\u4e00-\u9fa5] 中文字符
量词
n+ 匹配至少一个n
n* 匹配任何包含0个或多个n
n? 匹配任何包含0个或1个n
n{X} 匹配包含X个n的序列的字符串
n{X,Y} 匹配含X至Y个n的序列的字符串
n(X,) 至少包含X个n
n$ 结尾为n
^n 开头为n
?=n 匹配任何其后紧接指定字符串n的字符串 判断是否后接记得括号括住,有区间和子正则的原因
?!n 匹配任何其后没紧接n的字符串
其他
reg.global 查看是否全局匹配
.ignoreCase 查看是否无视大小写
.multiline 查看是否有跨行
.source 查看正则本体
对象方法
RegExp.compile 编译正则表达式
.exec 检索字符串中指定的值。返回找到的值,并确定其位置 如果带g 每次会记忆上次位置,找下
-一个 叫游标
.test 检索字符串中指定的值。返回true或false
支持正则的字符串函数
.search
.match 返回含目标索引的一些信息
.replace 按正则替换
.split 按正则拆分
反向引用
/\w\W \2\1/ str.replace(str,$2$2$1$1)
字符串
replace
不改变自身,而是返回一个新的 可以是正则参数(reg,'') 贪心匹配原则 可实现特殊需求如只去前面空格
笔试题知识点
前端undefind等于null
未定义,console.log直接用会报错
访问原型链,需要再看看
typeof优先级低,前端点优先度高 typeof数组是object
str.split,返回字符串数组
parseInt(3,0)=3 浏览器默认纠错
未定义fn 函数表达式在if中恒true
obj.Slice()类数组变数组.需要原型链或call
bind() 类似call,返回一个函数不执行 会将函数this锁定为传入的对象,后再跟参数的话,该参数值锁定
立即执行函数,有时候可以避免闭包产生的问题