文章目录
浏览器内核
IE trident
Chorm blink
firefox Gecko
Opera webkit
Safari webkit
解释型语言:解释一行执行一行,将代码转换成机械码。执行速度相对较慢,可以跨平台。
编译型语言:先将代码翻译成系统可以识别文件,再将文件转换成机械码,执行速度相对快, 不能跨平台。
js是解释型语言并且是单线程的。
script 标签不能同时外部引用和内部引用,(内部引用不会生效)
变量
变量 b变量的名字必须以字母、_、$开头 变量名可以包含数字 不可以用系统的关键字保留字做为变量名
var a = 0,
b= 1,
c= 3;
数据类型:
1、原始值 Number,Boolean,String, undefinde, null steck(栈):first in last out
undefinde:变量声明了没有赋值。
null:占位
2、引用值
array, Object, function , 。。。 data , RegExp heap(堆)
唯一区别: 复制形式不同
3.typeof 返回的六个值为:number、string、boolean、undefined、object、function。
书写规范
for ,function , if 后面不用加很分号
错误类型
错误分两种:
1、低级错误:(语法解析错误) SyntaxError 语法解析错误
2、逻辑错误:(标准错误) ReferenceError 引用错误。
js语法错误会引发后续代码终止,但不会影响其他js代码块。
js运算符
+
数学运算、字符串拼接
任何数据类型加字符串都等于字符串。
0/0 //NaN 1/0 //infinity
// ++ -- += -= /=
var a = 10;
document.write(a++); // 10 document.write(a); 11
document.write(++a); // 11
先计算,后赋值
赋值的顺序,自右向左。 计算的顺序,自左向右
var a = b = 10;
var a = 10;
var b = ++a - 1 + a++; ++a时,a的值为11 , -1 为 10 , 加 a 此时a的值为11,所以结果为10 + 11 得 21.
document.write(b + " " + a); // a = 12 b = 21;
a += 1 相当于 a = a +1;
a %= 1 相当于 a = a%1;
1.比较运算符
var a = 2 > 1; // true
>,<,>= ,<=,==,!=都是比较运算符,他们的返回结果是true或false。
当两个字符串相比较时,比较的时对应的ascII码的值。
var a = '10' > '8' // false
undefined == undefined // true
Infinity == Infinity // true
NaN == NaN // false
比较的是字符串‘1’,‘0’与‘8’的asccII码。1的ascII小于8的ascII,0的ascII小于8的ascII,所以‘10‘ < ’8‘.
如果一个不是字符串,并且两个都是原始类型,将他们都转换为数字进行比较。
NaN与任何数字比较得到的结果都是false。
Infinity 比任何数字都大。
-infinity 比任何数字都小。
NaN < Infinty // false
如果其中一个是对象,将对象转换为原始类型。
相等比较
== 、 !=
一、两端的数据类型相同,直接比较两个数据本身是否相同(两个对象比较地址)。
二、两端的类型不同
1). null 和 undefined, 他们之间相等,和其他原始类型比较则不相等。
null == undefined // true
null == 0 // false
undefined == 0 //false
2). 其他原始类型,比较时先转换为数字,再进行比较。
3). NaN与任何数字比较都是false,包括自身。
4).Infinity和-Infinity,只能自身和自身相等。
5). 对象比较时,要先转换成原始类型再进行比较
=== !==
1.两端类型相同,规则和相等比较一致。
2.两端类型不同为false。
null === undefined //false
null == undefined // true
2. 逻辑运算符 && || !
只有 undefined, null, NaN, “”, 0, false 转换成boolean值以后为false,其他值都会转为真。
var a = 1 && 2; // 2
var num = 1 || 3;
var n = !123;
与运算符会先看与运算符前面的表达式转换成boolean是否为真,如果为真,那么它会看第二个表达式转换为布尔值的结果。如果只有两个表达式,会直接返回第二个表达式的值。
当第一个表达式的值为false时,直接返回第一个表达式的值。
或运算符当第一个表达式结果为真时,返回第一个表达式。如果第一个表达是为假直接返回第二个表达式的值。
非运算符会将表达式转换成布尔值后取反。
算数运算符
其他数据类型使用算数运算
1.除加号之外的算数运算符。
将原始值转换为数类型(自动完成转换),然后进行运算。
bollean:true =》 1, false =》 0.
string:如果字符串内部是一个正确的数字,直接变为数字,如果是一个非数字,则得到NaN(能识别Infinity,不能把字符串内部的东西当作表达式)。
null:+ null =》 +0 ; - null =》 - 0。
undefined:undefined =》 NaN;
2.加号运算符
-加号运算符一边有字符串,含义变为字符串拼接。
将另一边的其他类型,转换为字符串。
数字 -》 数字字符串。
boolean =》 boolean字符串
null =》 “null”
undefined =》 ”undefined“。
+”“ =》0.
字符串转换时会忽略前后空格。
自增和自减
基本功能
一元运算符
++:将某个变量的值自增1
–:将某个变量的值自减1
细节
自增自减表达式
x++: 将变量x自增1,得到的表达式的值是自增之前的值。
++x: 将变量x自增1,得到的表达式的值是自增之后的值。
x–: 将变量x自减1,得到的表达式的值是自减之前的值。
–x: 将变量x自减1,得到的表达式的值是自减之后的值。
优先级
从高到底依次是:
++ --
* / %
+ -
优先级的运算细节:
- 从左到右依次查看
- 如果遇到操作数,将数据的值直接取出
- 如果遇到相邻的两个运算符,并且左边的运算符优先级大于等于右边的运算符,则直接运行左边的运算符
for循环
for(var i = 0;i < 10; i++) {
document.write('a');
}
/*
1.先执行var i = 0;
2.if(i < 10) {
document.write('a');
}
3.i++
4.然后重复执行步骤2和步骤3.
*/
var i = 0;
for(; i < 10; ) {
document.write('a');
i++;
}
/*
与第一种for循环的写法意思相同,for循环的执行顺序没变。
*/
if 判断
包装类
var num = 4;
num.len = 3;
console.log(num.len); // undefined
/* num 作为原始值是不会有属性和方法的。系统会隐式的将num转化为new Number(4).len = 3,然后执行delete方法将该属性删除。当再次访问num.len时,又重新将num.len 转换为new Number(4).len,此时得到的值为undefined。
*/
var arr = [1,2,3];
arr.length = 2;
console.log(arr); // [1,2]
/* 当修改数组的length 属性时,会将数组截断。此时将arr的 length属性变为2,则arr为[1,2]。
*/
var str = 'abc';
str.length = 2;
//new String('abc).length = 2 delete
//new String('abc').length 原本new String()上就有length属性,返回的就是字符串的长度
console.log(str.length) //3
Date构造函数
UTC和GMT
GMT:格林威治时间。太阳时,精确到毫秒。
UTC:世界协调时。以原子时间为即使标准,精确到纳秒。
UTC和GMT之间误差不会超过0.9秒
GMT +0800 东8区
时间戳
数字
GMT时间 1970-1-1 凌晨 到某个时间 所经过的毫秒数
var d = new Date(2015, 5 , 1, 13, 14, 15 ,200); //Mon Jun 01 2015 13:14:15 GMT+0800 (中国标准时间)
d.toISOString() // "2015-06-01T05:14:15.200Z" 零时区的时间
new Date 里的参数分别为年、月、日、时、分、秒、毫秒,如果new Date里有1个参数时参数类型为数字,表示传入的是时间戳(从1970-1-1凌晨+/-时间戳,有时间戳的正负决定+/-)。如果不传参数,表示当前时间。
注意:月份是从零开始记录的。
如果参数缺失,日期部分默认为1,时分秒毫秒默认为0.
月、日、时、分、秒/毫秒,均可以传递负数, 会根据指定日期进行计算。
new Date(2015, -1); //Mon Dec 01 2014 00:00:00 GMT+0800 (中国标准时间)
new Date(2015, 2, -1); //Fri Feb 27 2015 00:00:00 GMT+0800 (中国标准时间) 日期是从1开始计算的,所以传入-1相当于减了两天。
日期的运算
日期对象的valueOf方法返回的是数字类型的时间戳。因此日期对象可以进行数学运算。当作+法运算时会调用对象的toString方法,所以变成了字符串拼接。
Math四舍五入的方法:
方法 | 注释 |
---|---|
Math.floor | 将数值进行向下取整 例如:Math.floor(123.456) //123 |
Math.ceil | 将数值进行向上取整 例如:Math.floor(123.456) //124 |
Math.round | 将数值四舍五入成整数 例如:Math.round(123.666) //124 |
parseInt | 将数值舍弃小数部分转换成整数 例如:parseInt (123.666) //123 |
toFixed() | 将数值四舍五入成整数 例如:143.666.toFixed(2) // '143.67 ’ 注意toFixed的返回值为string类型 |
因此我们需要写一个能返回数字类型的值还并且能够四舍五入的方法:
function round (num,d){
num *= Math.pow(10,d);
num = Math.round(num);
return num/Math.pow(10,d);
}
console.log(round(123.456,2)) //传2为保留两位小数四舍五入
console.log(round(234.567,0)) //传0 为数字本身四舍五入
console.log(round(161,-1)) //传-1为整数部分四舍五入
console.log(round(168,-1))
输出结果如下:
思路:首先要进行四舍五入就会用到Math.round() 的方法。观察Math.round 的行为:Math.round的返回值为整数,并不能对小数进行保留。
因此我们可以通过扩大倍数(小学数学思想)来进行四舍五入,小数每扩大10倍小数点就会向后移动一位。比如求161.25四舍五入并保留一位有效数字:
var a = 161.25*10; //a 1612.5
a = Math.round(a); //a 1613
a/10 = 161.3 //因为前面将数字扩大了10倍,为保持数值不变最后的结果应除以原来扩大的倍数。
对于Date对象的小技巧
new Date().getMounth()的返回值为 0 -11;
如果 new Date(year,mouth,0).getDate();此时的返回结果为当前月最后一天。
如果当传入的日期为0时,则查询的getDate的值会返回上个月最后一天的值。
适用场景:日历。
看下面代码:
console.log(1 + undefined) //NaN
console.log(1 + null); //1
console.log(null + undefined); //NaN
console.log(true + false); //1
console.log(3 +'6'); //'36'
console.log(2 +[]); //'2'
console.log(2 +{a:2}); //'2[object Object]'
console.log([] + {}); //'[object Object]'
console.log({} + []); //['object Object]'
console.log(3 + {}); //'3[object Object]'
console.log({} + 3); // '[object Object]3'
console.log(1 * []); //0
console.log(1 * [2]); //2
console.log(1 * [2,3]); //NaN
console.log(1 * {}); //NaN
当进行加法运算时会进行隐式类型转换,如果加号两边的值不是引用类型且不为字符串类型,加号两边的值会先进行数值类型的转换。
Number(undefined) 的 值为 NaN,因此 1 + undefined 的值为NaN,Number(null) 的值为0。true 和 false 分别转换成0和1。当+号遇见字符串时会按照字符串拼接的规则执行。当+号遇见数组时,会将数组的两个中括号去掉,里面的值加上“”,因此2 + [] 的值为’2’。当*遇见[]时,会将[]的值转换为“”,“”转换为0。当+号遇见对象时会调用Object的toString方法将对象转换为字符串,对象转换的结果为’[object Object]’,所以3 + {}的值为 ‘3[object Object]’。
正则
匹配输入汉字:js /^[\u4e00-\u9fa5]{2,6}$/
字符集:
[字符范围 ]
[^字符范围] 对字符范围取反
量词:
* 匹配0个或多个
+ 匹配1个或多个
? 匹配0个或1个
{n} 匹配n个
{n,} 匹配>=n个
{n,m} 匹配n-m个
//test方法
var reg = /abc/g;
console.log(reg.lastIndex, reg.test("111abc111abc111"));//0 true
console.log(reg.lastIndex, reg.test("111abc111abc111"));//6 true
console.log(reg.lastIndex, reg.test("111abc111abc111"));//12 false
console.log(reg.lastIndex, reg.test("111abc111abc111"));//0 true
console.log(reg.lastIndex, reg.test("111abc111abc111"));//6 true
console.log(reg.lastIndex, reg.test("111abc111abc111"));//12 false
正则匹配为全局匹配多次调用test方法会出现上面的情形,当匹配成功以后他会从上次匹配成功的地方继续往后匹配,直到返回false才会复位。
如果没有开启全局匹配每次匹配都会从0的位置开始。
贪婪匹配
正则表达式会尽可能多的匹配满足表达式内容的字符串。
var reg = /\d+/g;
console.log(reg.lastIndex, reg.test("111abc111abc111"), reg.lastIndex);//0 true 3
正则会找到"111"而不是"1"或者"11"。
正则默认使用贪婪模式匹配。
var reg = /\d+?/g;
在正则的量词符号后面加上"?"表示开启非贪婪匹配模式。即尽可能少的匹配符合规则的字符串。
字符串的split方法也可以将正则作为参数传入。
var s = "sfsdfdsfd,fgdfdfgdf fdgdfgdg-dfgfdgdf\tgfdgdgffg";
var result = s.split(/[,\-\t]/);
console.log(result); //["sfsdfdsfd", "fgdfdfgdf fdgdfgdg", "dfgfdgdf", "gfdgdgffg"]
字符串的replace方法
replace方法并不会修改原来的字符串会返回一个新的字符串。
replace的第二个参数可以传一个函数。
捕获组
var s = "2015-5-1, 2019-6-19, 2000-04-28";
var reg = /(?<year>\d{4})-(?<mounth>\d{1,2})-(?<day>\d{1,2})/g;
while(result = reg.exec(s)) {
console.log(result)
}
会得到如下结果:
正则表达式reg
中每一个小括号表示一个捕获组,exec
方法返回一个数组,数组里的第一个元素表示匹配到的字符串,后面的元素依次(按照捕获组的书写顺序从左到右)表示每个捕获组匹配到的内容。
在捕获组前面加上?<捕获组名称>
来给每一个捕获组命名。exec
方法返回的
数组中groups
属性可以查看。如果没有给捕获组命名则groups
属性的值为undefined
。
非捕获组
/(?:\d)/
由于捕获组占用执行效率,所以当我们不需要捕获组时只要在正则表达式中的小括号开头部分加上?:
就可以了。
str.replace(reg, function(match,g1,g2,g3){
})
s.replace(reg,"$1/$2/$3");
上面字符串的replace方法中,g1,g2,g3 和 $1,$2,$3就是捕获组。
反向引用
var s = "aaabbbccccc"
//找出该字符串中连续的字符
var reg = /(\w)\1+/g;
while(result = reg.exec(s)) {
console.log(result[1];
}
\1
表示匹配和第一个捕获组一模一样的内容。
正向预查
检查某个字符后面的字符是否满足某个规则,该规则匹配的结果不会在整个表达式的匹配结果中返回。
var s = "dffsdf544543dsfsdf543553dfdsdf"
//匹配所有后面是数字的字母
var reg = /[a-zA-Z](?=\d+)/g;
while(result = reg.exec(s)){
console.log(result)
}
当在小括号开头部分加上?=
时表示正向预查,此时\d+
匹配的数字并不会在result中出现,并且这里的小括号不是 捕获组。
var s ="3345678";
var reg = /\B(?=(\d{3})+$)/g;
s.replace(reg,function(match,$1){
console.log(match,$1);
})
负向预查
检查某个字符后面的字符是否不满足某个规则,该规则匹配的结果不会在整个表达式的匹配结果中返回。
var reg = /(?!\d+)/g;
当在小括号开头部分加上?!
时表示负向预查。
浏览器dom操作
- 父元素.appendChild(元素):在某个元素末尾追加一个子元素。
- 父元素.appendBefore( 待插入的元素, 哪个元素之前) 第二个参数为null会将元素添加到最后。
- 关于insertAfter:父元素.insertBefore(待插入的元素, 哪个元素之前.nextElementSilbing)
- 父元素.replaceChild(替换的元素, 被替换的元素)
创建和删除元素
创建元素
document.creatElement("元素名")
克隆元素
- dom对象.cloneNode(是否深度克隆): 复制一个新的dom对象并返回。
- 如果是深度克隆会将要克隆元素的innerHtml部分一起克隆,否则只会克隆元素本身,元素里面的内容并不会被克隆。
- 元素.children() 会返回实时的所有子元素集合。
删除元素
- removeChild: 父元素调用, 传入子元素 通过父元素删除子元素
- remove: 元素.remove() 把自己删除
控制dom元素的类样式
- className: 获取或设置元素的类名
- classList:dom4的新属性,是一个用于控制元素类名的对象。
- add:用于判断一个类名是否存在
- remove:用于移除一个类名
- contains:用于判断一个类名是否存在
- toggle:用于添加/删除一个类名
获取样式
- dom.style:得到行内样式对象。
- window.getComputedStyle(dom 元素): 得到某个元素最终计算的样式。
- 可以有第二个参数,用于得到某个元素的某个伪元素样式。
设置样式
- dom.style.样式名 = 值;
事件
mouseenter 和 mouseover的区别(mouseleave与mouseout):
- mouseover 和 mouseout 不考虑子元素,从父元素移动到子元素,对于父元素而言,仍然算作离开。
- mouseenter 和 mouseleave , 考虑子元素, 子元素仍是父元素的一部分。
- mouseenter 和 mouseleave 不会冒泡。
事件对象
- e.button 0 : 左键 1 : 滑轮 2 : 右键
- e.ctrlKey 当触发事件时是否按下了ctrl键
- e.altKey 当触发事件时是否按下了alt键
- e.shiftKey 当触发事件时是否按下了shift键
位置:
- page: pageX、pageY,当前鼠标距离页面的横纵坐标。
- client:clientX、clientY ,当前鼠标距离视口的横纵坐标。
- offset: offsetX、offsetY, 鼠标相对于事件源内边距(内容 + padding )的坐标。
- screen:screenX、screenY, 鼠标相对于屏幕-
- x、y,等同于clientX、clientY
- movement:movementX、movementY,只在鼠标移动事件中有效,相对于上一次鼠标位置,偏移的距离。
KeyboardEvent - code: 得到按键字符串,适配键盘布局。
- key: 得到按键字符串,不适配键盘布局。 能得到打印字符。
window和document里的事件 - load、DomContentLoaded、readystatechange
- load:页面中所有资源全部加载完毕的事件。
浏览器渲染页面的过程:
1.得到页面源代码
2.创建document节点
3.从上到下依次执行代码
4.将元素依次添加到dom树中,每添加一个元素,进行预渲染
document.DomContentLoaded事件:dom树构建完成后发生。
readyState: loading、interactive、complete
interactive:触发DomContentLoaded
complete:触发window的load事件。
console.log(document.readyState);
document.onreadystatechange = function(){} //当html状态发生改变时触发
beforeunload: window的事件,关闭窗口时运行,可以阻止关闭窗口 高版本的谷歌浏览器不支持
unload:window的关闭事件,关闭窗口时运行。
scroll
窗口发生滚动时运行的事件
通过scrollTop和scrollLeft,可以获取和设置滚动距离。
获取整个网页的滚动高度:
document.documentElement.scrollTop + document.body.scrollTop;
resize
监听视口尺寸变化的事件。
window.screen.height:获取整个屏幕的高度。
window.outerHeight:获取浏览器的整体高度。
window.innerWidth:获取浏览器窗口的宽度(包含滚动条)。
document.documentElement.clientWidth:获取浏览器视口的宽度(不包含滚动条)。
某个元素的offsetWidth:获取元素(包含边框和滚动条)的宽度。
某个元素的clientWidth:获取元素(不包含边框和滚动条)的宽度。
某个元素的scrollHeight:获取元素里实际内容的高度。
contextmenu: 右键菜单事件
paste 粘贴事件
copy 复制事件
cut 剪切事件
inp.onpaste = function(e) {
var txt = e.cli
pboardData.getData("text/plain); //获取剪切板里类型为text/plain的数据。
if(txt && /\d+/.test(txt)){
}
}
元素位置
- offsetParent
获取某个元素的第一个定位的祖先元素,如果没有, 则得到body。
body的offsetParent为null。
- offsetLeft、offsetTop
相对于该元素的offsetParent的坐标
如果offsetParent是body,则将其当作是整个网页(会有额外8px的空隙 ) - getBoundingClientRect
该方法得到一个对象,该方法记录了该元素相对于视口的距离。
window
open
打开一个新窗口 window.open()返回一个window对象
<iframe name="myiframe" src="" frameborder="0"></iframe>
window.open("https://ww.js.com","_blank");
window.open("https://ww.js.com","myiframe");
location
属性 | 描述 |
---|---|
hash | 返回一个url的锚部分 |
host | 返回一个url的主机名和端口 |
hostname | 返回url的主机名 |
href | 返回完整的url |
pathname | 返回url路径名 |
port | 返回一个url服务器使用的端口号 |
protocol | 返回一个url协议 |
search | 返回一个url的查询部分 |
reload方法:刷新当前页面。
history
go方法
back方法
forword方法
console
log方法:打印对象的valueOf的返回值。
dir方法:打印对象结构