读了不知道几遍,每次都没总结合做笔记,所以很多内容都记不住,如果平时没应用到实际中,那知识跟像过眼云烟,于是还是谢谢博客记记笔记,好好学习天天向上。
原教程链接: http://javascript.ruanyifeng.com/
let's go!
1. var a=1; 效果类似a=1,区别在于前者可用delete删除,后者不可
2.变量只声明,但未定义,值就为undefined,表示无定义,
此处啰嗦下 undefined 和null 的区别,可见http://www.ruanyifeng.com/blog/2014/03/undefined-vs-null.html,
undefined就是未赋值,缺少值,应该要有值,但是却没定义,比较多情况
null 没有对象,不应该有值,主要注意null作为原型链的终点,Object的原型对象的原型对象就是null,null没有原型对象了,终结,
Object.getPrototypeOf(Object.prototype) //
null
undefined == null //true
Number(null) 0
Number(undefined) Nan
3.关于变量提升,js引擎的工作方式是先解析代码,获取所有被声明的变量,然后在一行一行运行,导致会存在变量提升的现象,会把用var命令声明的变量提升,
console.log(a);var a= 1; 结果是undefined, 其实是这样运行的: var a; console.log(a);a=1
4.es5的区块不作为作用域,和es6的区块作为作用域不同
5.switch 的参数和case 比较是用===严格相等运算符,所以不强制发生类型转换,
6.感觉不重要,但还是记下,标签,
top:
for (var i = 0; i < 3; i++){
for (var j = 0; j < 3; j++){
if (i === 1 && j === 1) break top; //或者continue top
console.log('i=' + i + ', j=' + j); } }
7.js中的数据类型,主要有:字符串,数字,布尔值/(前面三个都叫原始数据类型),对象(函数,数组,狭义对象),null 和undefined
8.通过三种判断方式可以判断数据的类型
1.typeof 数据(先学这个) 2,数据 instanceof 对象 3,Ojbect.prototype.toString()
typeof 结果,记住结果返回的都是字符串
原始类型:字符串 string 数字 number 布尔值 boolse
合成类型(对象)
{} object
[] object
以上两种可以进一步通过 数据 instanceof Array ——》false 不是数组,true 是数组来区分
null
null object(不能说明null是对象,因为历史遗留原因而返回object)
undefined
返回undefined,关于undefined有个使用方法,typeof undefined并不会报错,可以用来判断某个变量没有声明(并非没定义,没定义直接可以用===undefined判断),
错误做法 if(v)报错, 正确 if(typeof v === "undefined")
9.关于布尔值,除了undefined, null, false, 0, NaN, ""或者''(空字符串)会转化为false,其他都是true,包括[]和{}空数组和空对象
10.关于数值,js浮点数按64位二进制存储,
第一位 符号位,0 + 1 -
2-12 : 指数部分
13-64: 小数部分
(精度):有效数值第一位默认为1,但是不存在64位中,所以有52+1个二进制位表示,所以-(253-1)到253-1 个整数可以精确表示
(数值):指数部分长度为 11,所以数值范围21024到2-1023 ,
指数部分如果超过 1024,js会返回Infinity,如果小于-1023,js会返回0;
特殊数值 -0 === +0, 0 === -0, 0 === +0
( 1 / +0)Infinity (1/-0) -Infinity
NaN:非数值,用isNaN判断,0/0 NaN NaN === NaN /false(是js里面唯一不等于自身的值)
Infinity,无穷大,isFinite判断是不是正常值,NaN和Infinity都返回false,
11.字符串,其实字符数值,一些数值的属性都可以用,比如length,比如a[0]可以返回第一个字符(2个字节,16位utf-16格式储存,也是unicode形式储存,)但是不能改变字符串的字符,有charAt(i)返回i位的字符,charCodeAt(i)i位字符的unicode值
Base64编码方法,把任意字符转化为可打印字符,btoa() 转化为base64,atob()还原编码,
只能直接转化 ASCII码,如果转化非ASCII码值,要先这
样 btoa(encodeURIComponent(str)),decodeURIComponent(atob(str));
encodeURIComponent不会对ASCII字符和数值以及_ -.! ~*()编码,其他都会变成一个或多个十六进制的转移字符替换
12.对象,三种生成方式,
1.var a={}
2.var a = new Object();
3.var a = Object.create(Object.prototype)
对象的引用是地址拷贝, var a1 = {}, a2 =a1, a2.a=1, a1.a就等于1,如果变成原始数据类型,就只是值拷贝;
({foo:123})行首如果是大括号,加上()之后就是代表对象,不然只是个代码块
读取不存在的键不会报错,会等于 undefined,
tips: 'a' in window来判断一个变量是否声明过
Object.keys(o)返回一个包含键明的数组,delete 键名可以用来删除属性(存在和不存在都会返回true,除非某个属性的configurable=false,才会返回false,还有也不能删除继承的属性,但是这是返回true,也不能删除 var 命令声明的变量,)
for(var i in o)可以遍历全部可以遍历的属性,跳过不可遍历,不跳过继承的属性,用o.hasOwnProperty(key)可以用来判断是不是自身属性
13.数组,是一种特殊的对象typeof返回object,键名是序列数,可以用Object.keys(arr),返回序列数值的数组
可以添加数值,但是健名一定要是可以转化为整数的值,添加后有效, length改变,
in 字符串可以用在对象也可以用在数值,如果某个位置是空位,返回false ,arr[100]=1, 之前的100个键名都返回空,
for(in)会遍历非数字建值,虽然这个建值并且没有算入length中,也不会返回,一遍遍历用for(),while
delete删除元素,不会影响length,只是变成undefined
关于空位 [, , ,]length是2,最后一个逗号后面如果没有成员,忽略,for in ,foreach, keys()都会过滤掉空位,但如果是[undefined,undefined,undefined]就都不会过滤
14.函数,
函数声明的方式:
1.function 命令声明(存在变量提升,会声明和赋值)
function a() {}
2.表达式,把一个匿名函数赋值给一个变量
var print = function() {};
3Function 构造函数,
var add= new Function(x,y,'return x+ y'),总是把最后一个参数当做函数体,
属性,
f.name,
1.function f1(){} f1.name /f1
2.var f2 = function() {} f2.name /f2
3 var f3 = function myname(){} f3.name /myname(只在函数内有效)
f.length 返回定义时的参数个数,不是调用时的参数个数,arguments.length就是调用时参数的个数
f.toString()返回源码
参数,如果参数是原始类型,就是传值传递,如果是对象,数值,或其他函数就是传地址传递,修改他的属性会生效,但是注意若干把对象整个改了,就切断来了地址,也不会影响到原来的了,如果要改,可以利用 window对象进行传地址
arguments函数参数,是个类数组对象,通过Array.prototype.slice.apply(arguments)可以转化成数组
闭包,一个声明定义在另一个函数体内的函数,因为函数存在作用域概念,所以可以通过闭包读取函数内部属性,还有要注意的是闭包的作用域是在他声明的函数体内,而不是调用时的,闭包还有个作用是保存他声明定义时的状态
例子:
function createIncrementor(start) { return function () { return start++; }; }
var inc = createIncrementor(5);
inc() // 5
inc() // 6
inc() // 7
立即执行函数
js规定function放在行首,都代表函数的声明,所以后面不能跟(),表示执行,所以立即执行函数的形式有两种
1.(function(){}()); 2(function(){})();
主要用 ()把声明变成表达式,也可以用其他运算:
var i = function(){}(); 不把function放行首
true && funcition(){}();
0,function(){}
!function(){}();
+
-
~
eval_r()执行字符串,没有自己的作用域,作用域是当前(不推荐用),即使是间接调用
var a = 1;
function f() { var a = 2; var e = eval; e('console.log(a)'); }
f() // 1
15运算符
+ a + b
1,如果a或者b是对象,先执行valueOf(,一般对象会返回原对象),如果结果是对象,就执行toString,(一般对象结果是返回字符串[object, Object],),但两个运算子有一个是字符串的时候,都转化为字符串,进行拼接运算,如果都是数值,就进行数学运算,只有加法会这样麻烦,如果其他运算符,比如减肥,乘法,都直接转化为数值进行运算(使用Number),
数值运算符 : +a, 会把a变成数值, 负数值运算符(结果变成负数而已)
2比较运算符,如果都是字符串,按字典顺序(实际是unicod吗点),否者其他原始类型数据都转化为数值,如果是对象,对象的方式跟加法的一致,
严格相等 ===
不同类型马上 false,如果是同一类型的原始数值,值相同就true,
注意 NaN ===NaN false
同一类型的复合型值,比较的是地址,是否指向同一个对象,如果是其他比较运算符,比较的是值,
相等 ==
会进行强制转化
原始类型的数据会直接变成数值进行比较,即用 Number()
对象和原始类型比较,对象转化为那个原始类型,进行比较
undefined和null和其他类型的值比较都是false,但是undefined· == null true
void 表达式, 执行一个表达式,并返回undefined,
强制转化类型:
1Number, 如果是字符串,布尔值,null,undefined,变成数组或者NaN(例如'324abc',如果用parseInt('311abc')会变成311, ''->0, undefined-> NaN, null-> 0 ),Number会自动去掉之前和之后的空格
如果是对象型的复合数据类型,一律返回 NaN
步骤是: 对象: 先用valueOf判断是不是返回对象,如果是先调用对象的toString(),如果返回的还不是原始类型的值,就报错,如果是的话就直接对返回值使用Number,
自动转化为数值的情况,数值运算符,除了加法以为的算术运算符
2.String()对象的转化规则是,先toString(),再valueOf,纯对象变成"[object Object]",数组是"1,2,3"
3.Boolean(),除了 undefined,null, -0,+0,0,NaN,''为false,其他都为true,
16错误机制,
Error对象的派生对象: SyntaxError,解析是出错,ReferenceError,undefined错误,RangeError,超出有效范围,TypeError,不是预期类型,比如new 123这种,URIError,Uri函数相关参数不对的情况,这些函数主要有encodeURI()、decodeURI()、encodeURIComponent()、decodeURIComponent()、escape()和(),
EvalError,eval执行时抛出错误
自定义错误方法:
function myError(mess){this.message = mess ||''}
myError.prototype = new Error();
my.prototype.constructor = myError;
new myError('my error');
throw用来抛出一个错误对象,也可以是其他数据
try{
throw new Error(1);
不会执行;
} catch{
2
return 4/throw 4(第一个return被finally的覆改掉,但是return或者throw会执行,只是返回的时候要等finally的执行完才返回)
}finally
3
return 4
不会执行
}
不会执行(因为 return了)
如果没有 catch,会执行finally,但是不会执行后面这个模块之后的代码了
语法:
1对象:用new Object(a)===a (如果a是对象) true
如果 a是原始数据类型,则变成对应的对象,数值->Number对象,字符串->String, 布尔值-> boolean
对象的属性: 1.Object对象的静态方法,只能通过Ojbect对象调用,不能被继承,主要有Object.keys()获取对象的属性键名,并且返回数值,只遍历可遍历的自身属性,不包括继承的,Object.getOwnPropertyNames(),跟前者有点像,只是他可以遍历不可遍历的属性,比如数值的length,
Object.getPrototypeOf(),获取对象的Prototype对象,
实例方法
valueOf(),一般对象返回对象本身,
toString() ,每个值都有一个toString方法,返回不一样的东西,但是通过Object.prototype.toString.call(),可以返回类型,比typeOf更加精细
2Array对象
var arr = new Array(2) 可以不用写new() [undefined,undefined] 0 in arr /false,虽然每个元素是undefined,但是,不能得到键名,Array会因为参数的不同而结果不同,比如new Array(1,2) 就等于[1,2]
Array的静态方法,isArray()判断是不是数值, typeof 数值,返回的是object
实例方法, valueOf()返回数值本身,toString,'1,2,3'字符串
push(1,2,3)在数值后面推入三个数,如果参数要是数值,可以用Array.prototype.push.call(a,b)其中a和b是数值,也可以用a.push.call(a,b),该方法也可以应用到对象,添加后对象变成类数组对象,[].push.call(a, 2), 其中a={a:1},运行后,a变成{a:1,0:2,length:1},length取决于数字键名,
pop()删除最后一个元素,并返回删除元素,空数组pop,返回undefined,不会报错,
pop和push 体现了栈,后进先出
shift(),删除的是第一个元素,unshift()在第一个位置添加元素,reverse(),颠倒元素位置
splice(删除起始位置,删除个数,之后要在删除位置加入的元素),第一个元素如果是负数代表倒数,如果只传一个参数,代表把数组变成两部分,把起始位置之后的元素删掉
var a = [1, 1, 1];
a.splice(1, 0, 2) // []
a // [1, 2, 1, 1]
sort(),按字典排序(10111排在111前面)可以传一个函数参数,function(a,b){return a-b},返回值大于0就按ba从小到大
join(s), 返回一个用字符s隔开的字符串,如果元素是undefined,null,或者空位,会变成空字符
[undefined, , null].join('#') ‘#’
通过 Array.prototype.join.call('ab', '-') /a-b,因为字符可以算是字符数值
或者类数组对象也可以, obj={0:1, 1:2,length:2} 执行后变成1-2
[1].contact([2,3],[4])/[1,2,3,4]返回一个连接两个数组的新数组,等于(2,3,4),如果没有传参数,则返回的是她本身的浅拷贝,即引用,如果元素是复合型的值,新值拷贝的就是引用,改变会生效
slice(其实位置,结束位置后一个位置(可省)),返回这样一个部分,如果参数是负数,就是倒数
一个重要的用法就是把类数组对象变成真正的数组, Array.prototype.slice.call(obj)
[].map(function(v,i,arr){return},arr)会返回一个数组,map的第二个参数代表函数this的指针,注意,但元素是空位的时候回调函数不会执行,最后返回的那个数组也还是空位,
forEach(function(e,i,arr),arr)类似map,但是不会返回数值,注意他不会中断执行,会把所有元素遍历完,一样会跳过空位
filter(function(e,i,arr),arr)
some(function(e,i,arr),this)只有一个返回true就true,
every(...)每个都符合
reduce(function(x,y,当前位置(0),原数组))从左到右累计处理,x代表累计变量,默认为第一个元素,y当前变量,默认第二个元素,
reduceRight()从右到左
indexOf(s, 开始搜索位置)返回参数在数值中出现的第一个位置,没有返回-1
lastIndexOf,出现的最后一个位置
注意 NaN不适用,因为这个方法是用===,NaN不等于本身
包装对象 Number(),String(),Boolean(), valueOf()分别返回123,“abc”, true, toString()分别返回“123”,“abc”,“true”
原型数据可以自动被转化为临时包装对象,使用后立即销毁,只读不可修改
用包装方法,不用 new 可以直接返回对应的值(不是对象了),相当于 new 包装对象().valueOf()
Number(实例方法)
toString()
toFixed(小数位数0-20位)返回一个指定小数位数的字符串
toExponetial(科学计数法小数位数0-20位)返回指定小数位数的科学计数法
toPrecision(有效数位)返回有效数位的字符串
String() 字符包装对象,实际是类数组对象,有length属性
静态方法 String.fromCharCode(多个unicode码的参数,不支持大于0xFFFF的字符)
实例方法
charAt(位置)返回指定位置的字符,如果为负数,或者超出范围就返回空字符
charCodeAt()返回指定位置字符的unicode值,
contact(位置)链接两个字符,返回一个新的字符串,不改变原字符,和Array对象的contact一样
slice(),类似array的方法
substring()和slice差不多,但是区别在于,如果参数是负数会变成0,而不是变成倒数,而且如果第一个参数大于第二个参数,则会自动调换位置
substr(开始位置(如果是负数变成倒数),未传则表示第一个(如果是负数变成0))
indexOf(s,开始匹配位置(往后匹配))字符在对象里面的第一个位置,如果没有返回-1,lastIndexOf(s,开始匹配位置(往前匹配))最后一个位置
trim(),去掉空格,\t,\v,\n,\r,返回一个新的字符串,不改变原字符
toLowerCase()小写,toUpperCase()大写,都不改变原字符
a.localCompare(b)返回整数,<0,=0,>0,是按我们自己的语言顺序,比如‘B’> 'a' false, 但是用该函数就是true
match(s)返回数组,成员是匹配的第一个字符串,没有返回null,返回的数组具有index和input属性,分别代表匹配开始的位置和原始字符串
search()类似,但是返回的是index
repalce()
split(s,返回的最大成员数)用s分割字符串,返回的是数组,
Math是js的内置对象,不能作为构造函数,只能用静态方法
Date表示时间范围是距离1970年1月1日 00:00:00前后各1一亿天,
new Date()参数有多种形式
1.毫秒数,表示距离那一个的毫秒数,若干参数用Unix时间戳作为参数,必须乘1000,因为他是以秒的
2.字符串,格式为“月 日,年 时:分:秒” 如果省略时间,会默认为0,其实其他时间格式也可以,只要可以被Date.parse()方法解析,注意es5里如果YYYY-MM-DD会变成iso时间格式,时间默认是08:00:00,其他的就是00:00:00
3.多个参数,(年,月[日,时,分,秒,毫秒]),必须两个
注意
月: 0-11,时:0-23,分:0-59,秒:0-59,毫秒:0-999,除了日:1-31
时间的运算,如果是加法,就是字符串相加,如果是减法就是间隔毫秒数
Date静态方法
Date.now(),返回距离那个时间的毫秒数 window.performance.now(),提供页面加载到命令运行时的已经过去的时间,可以精确到千分之一,
Date.parse(),解析日期字符串,返回毫秒数,解析失败返回NaN
Date.UTC(),返回UTC(世界标准时间)时间(date默认读取本地时间)
Date实例方法
toString(),跟直接读取对象实例一样,
toUTCString()
toISOString(),对应的iso8601写法(以utc时间为准)和toJSON一样
toDateString()返回日期字符串, toTimeString()返回时间字符串,toLocalDateString()当地时间日期格式,toLocalTimeString()
getTime,获取距离那个时间的毫秒搜,跟valueOf一样
getDate,返回几号,
getDay,星期几,星期日:0,星期一:1
getYear,距离那个时间的年数,
getFullYear, 返回年份
getMonth,返回月份
getHours,小时
getMillisecondes,毫秒
getMinutes,分
getSeconds秒
getTimezoneOffset距离世界标准时间的差异,以分为单位
有一些对应的 UTC方法,例如getUTCDate(),以此类推
set。。。参照get,
也有对应的 UTC方法,例如setUTCDate()
valueOf(),类似
Regex
两种方式
1. /xyz/g 2 new Regex(字符串, 'g')
属性
ignoreCase 是否设置了i修饰符,只读,表示是否忽略大小写
global,是否设置g,
multiline,是否设置m
lastIndex 下一次开始搜索的位置,可读写,一般只有设置了g才有意义
source,对象的字符串形式,只读
test(s),返回是否匹配s,只要匹配就停止了,除非,在调用一次,这是设置lastindex才有用,即使设了全局g,也是要调用多次才可以继续搜索
exec(),返回一个数组(失败null)第一个是整个匹配的字符串,如果有组,第二个对应,第一个括号的匹配,第三个参数对应第二个括号,,只要匹配成功就返回,不会再进行之后的匹配(和match不一样,match是返回所有匹配的字符串)。返回的数组包括input原字符串,index整个模式成功匹配的开始位置,可多次使用 ,如果正则是空字符串,匹配成功,但返回空字符数组
字符串对象的方法,
match匹配的所有结果(失败null),lastindex对他没用,因为他是全部匹配
search返回第一个匹配的位置,否则返回-1,会忽略g,lastIndex也无效
replace(),第二个参数可以设置$&匹配的字符,$`匹配字符前面的字符,'后面,n第n个组的内容(从1开始算),$$美元符号,也可以是一个函数,function(匹配的字符串,第一个组的匹配,第二个组的匹配。。。。匹配位置,原字符串)
'abc'.replace('b', '[$`-$&-$\']')// "a[a-b-c]c"
如果参数包括(),则组匹配也会返回,紧跟在对应匹配的位置
'aaa*a*'.split(/(a*)/) // [ '', 'aaa', '*', 'a', '*' ]
正则表达式的字符包括字面量字符和元字符,
元字符:
1 点字符(.)代表除了\r,\n,行分割(\u2028)和段分割符(\u2029)以为的所有字符
2 位置字符, ^开始$结束
3.选择字符 | 或者的意思,包括之前和之后的所有字符, ab|cd,包括ab, 或者cd,而不会b或者c
4.转义字符,需要的字符有 ^,$,[ , . ,( , ), |, * ,+ ? { , \\, 注意如果是用new RegExp得用两次,比如一般是\+,来匹配加法,如果用regexp得用\\+来匹配,
字符类 []
[abc]表示匹配abc当中一个就可以了
[^abc]脱字符,必须放在方括号的第一个位置,否则就不是这个用处了,匹配不能包括abc中的任何一个,用法: [^]可以匹配一切字符,包括换行符,
[a-z]a-z的范围中任何一个, [a-zA-Z0-9],-必须放在两个字符中间才有意义,不然就只代表字面意义
一些预定义的模式
\d [0-9],
\D [^0-9]
\w [A-Za-z0-9_]
\W[^A-Za-z0-9_]
\s 空格(包括制表符,空格符,断行符)[\t\r\n\v\f]
\S[^\t\r\n\v\f]
\b 词边界,也就是词与词之间间隔的符号,比如“abc abc”就是空格,
\B词于词没有边界
/\bworld/.test('hello-world') // true/\bworld/.test('helloworld') //false
/\Bworld/.test('hello-world') // false/\Bworld/.test('helloworld') // true
[\S\s]可以用来匹配一切字符,包括换行符,跟[^]一样
重复类
{n,m(可省略)}重复n到m次 lo{2,5},o重复2到5次,跟|不一样,他是前面或后面整个字符
量词类
? {0,1}
* {0,}
+{1,}
正则表达式是贪婪匹配,比如 a+来匹配aaa,match返回的结果是aaa,而不是a。可以在+后面加个?,就变成非贪婪匹配了,还有非贪婪*?
修饰符 i忽略大小写, g全局匹配 m多行模式,默认不加,针对^ 和$的行为,匹配事不会把换行符当做换行符,而是当做字符匹配, /word$/.test("hello word\n") false 加上m 返回true,^和$会匹配行首和行尾,知道多行,/^b/m.test('a\nb') // true
组匹配
match会返回组内匹配字符,但是不要用g修饰符,不然match不会返回组内字符,
可以用 \n表示第n个括号的内容,n从1开始,/(.)b(.)\1b\2/.test("abcabc"),true,其中\1表示第一个括号匹配的内容,这里是a,\2表示c
非铺获组
( ?:x)x代表组匹配,不返回改组的匹配内容,但是还是会匹配,
先行断言
x(? =y)只有x在y前面才匹配,并且组内字符y不返回
先行否定断言
x(?!y)x不在y前面才匹配,y同样不返回
JSON对象
严格的 json对象是这样的:
1.复合型的值只能是一般的对象和数组,不能是函数,正则,日期对象
2.简单型字符只能是字符串,数值(必须是十进制,不能是NaN,Infinity,-Infinity,),null,布尔值,(undefined)
3.字符串和键名只能用双引号
4最后一个元素不能加逗号
静态方法
stringify(值(可以是对像也可以是数组或其他的不一定是对象))把一个对象转化成一个严格的json字符串,可以被parse()还原,字符串会变成""abc""有两个双引号,如果对象中有个属性是函数,undefined,xml对象,就会跳过,如果属性中是数组, 数组里面有哪些,就变成null
JSON.stringify({ f: function(){}, a: [ function(){}, undefined ] }); // "{"a": [null,null]}"
stringify(正则)// "{}"
这个方法会忽略不可遍历的对象
第二个参数
1.数组(规定要转化的属性名,只有第一个参数是对象才有效)
2函数 function(key,value),如果返回undefined或者没有返回值,则这个属性被忽略
第三个参数
数字:表示每个属性要添加的空格数,不超过 10
字符串 :要添加每个属性前面的字符
如果第一个参数是个对象,并且有 toJSON方法,则直接用这个函数的返回值作为参数
parse方法,stringify的反向,
第二个参数可以是个函数,于 stringify里面一样的作用
属性描述对象
{
value:,
writable:(决定了value是否可以改变,默认true) ,
enumerable: (是否可枚举,默认true)
configurable:(默认true,如果false,不可删除属性,不可改属性描述对象的属性(除了value之外)) ,
get: 默认undefined,
set: 默认undefined
}
静态方法:
getOwnPropertyDescriptor(对象,属性)返回一个属性描述对象
defineProperty(对象,属性,属性描述对象)
defineProperties(对象,{属性名1:对象描述对象,属性名2: 对象描述对象2,。。。。})
如果设置了 get或者set,就不能一起定义value,也不能把writable设定为true,用这个两个方法设定的属性描述对象,3个属性描述对象的属性默认都是false。注意用var 声明时(其实是设置了一个当前环境变量的一个属性),configurable默认为false,不能删除,其他都可以
enumrable 可遍历性,用Object.prototype.propertyIsEnumerable,判断是否可枚举
如果为 false
for in (对应in )不会遍历(不管继承或者不继承的属性)
Object.keys(),不会遍历(也不会遍历继承的属性),如果要遍历自身所有属性(不管enumrale,),用Object.getOwnPropertyNames()
JSON.stringify()不会遍历,也不会遍历继承属性
configurable 设置为false时,设置其他属性,除了value(取决于writable),都会报错,但是writable从false设置为write才会报错
writable 如果派生对象的属性设置为false,继承对象对该属性赋值会失效,但是可以通过defineProoeryty定义,
get 属性名() {}
set 属性名() {}
对象拷贝(对象考虑要确定新对象和源对象有一样的原型对象,并且有一样的属性),如果属性描述对象中有存取器,直接用赋值进行拷贝只会拷贝值
可以用这种方式:
var extend = function (to, from) { for (var property in from) { var
descriptor = Object.getOwnPropertyDescriptor(from, property); if
(descriptor && ( !descriptor.writable ||
!descriptor.configurable || !descriptor.enumerable ||
descriptor.get || descriptor.set)) { Object.defineProperty(to,
property, descriptor); } else { to[property] = from[property]; } }
}
控制对象状态, Object.preventExtensions()(可以删除属性,但是不能调加新的属性,isExtensibl,false时,表示设置了preventExtensions)
isSealed())
。。。。差一节
面向对象
js没有类的概念,没有像c++那样的类对象来体现面向对象,js不是基于类,而是基于构造函数和原型链,构造函数里面的this指的是生成的对象实例,用new命令调用构造函数生成实例,如果没加new,则this指针指向顶层对象window
new的步骤如下:先创建一个空对象,作为对象实例,然后把对象的原型指向构造函数的prototype属性,然后把构造函数的this指针指向对象,完成
构造函数如果有 return语句,并且后面跟着一个对象(不是数字,字符串或者其他的东西),则new生成的是这个对象,否则不管怎样都是返回this对象,
如果是 new命令调用,则构造函数的new.target指向当前的函数,否则指向undefined
this指针很难,一般通过new创建实例的时候,this指向对象实例,但是可以通过赋值,改变this的指向,如果是在全局运行,则this指向window
var A = {
name: '张三',
describe: function () {
return '姓名:'+ this.name;
}
};
var B = {
name: '李四'
};
B.describe = A.describe;
B.describe()//姓名: 李四
只有用 obj.foo()这种方法,this才指向obj,其他的用法都是指向顶层环境:window(浏览器)或者global(node全局),module.exports(node模块环境中),严格模式下,this指针指向顶层对象会报错
// 情况一
(obj.foo = obj.foo)() // window
// 情况二
(false || obj.foo)() // window
// 情况三
(1, obj.foo)() // window
绑定 this的实例方法:
1.function.prototype.call(obj,参数1,参数2,。。。。)
obj应该是个对象,如果是空,null,undefined,就会指向顶层,如果是个原始数据类型,则会自动转化Wie对应的包装对象,一个用就是在实例函数覆盖掉原型函数的时候,可以通过Object.prototype.function.call(obj,参数)一样调用原来原型对象的方法
2.。。。。。.apply(obj,[参数1,参数2,...])
一个重要的用法是将一个类数组对象转化成正真的数组
Array.prototype.slice.apply(类数组对象)
3.....bind(obj),bind可以绑定一个参数,
var add = function(x,y){}, var a = add.bind(一个对象,5),a(6),执行时add里面的x就绑定5,运行时只要再绑定一个参数y 6就可以了,
注意 bind每次都返回一个函数,所以比如事件监听不能这样写
element.addEventListener('click', o.m.bind(o));
这样的话事件监听就取消不来了,因为找不到
element.removeEventListener('click', o.m.bind(o));失效
正确的写法是
var listener = o.m.bind(o);
element.addEventListener('click', listener);
回调函数的写法
callIt(counter.inc.bind(counter));
prototyoe原型对象
一般要这样写:
var MyArray = function() {}
MyArray.prototype = new MyArray();
MyArray.prototype.constructor = MyArray;
var mine = new MyArray();
每个对象都有一原型对象, Object.prototype 指向null,null没有自己的原型对象,其实每个函数都有prototype属性,他指向构造函数对应的原型对象,原型对象其实就是一个对象,并且有一个constructor函数,通过Object.getPrototype(对象)可以获取对象的原型对象
a(a只能对象,如果是undefined,null,或者其他原型数值,都返回false) instanceof b(b是个构造函数) a是不是b的实例(一个对象可以使多个对象的原型),相当于b.prototype.isPrototypeOf(a),
object.create(null) instanceof object //false
Object.getPrototypeOf(a),获取对象a的原型对象
Object.setPrototypeOf(a,b)返回一个设置a的原型对象为b的新对象,a一般放一个空对象{},也会对a进行改变
Object..create(a,b(可省略,一个属性对象,对象的属性是新对象的属性,属性是一个属性描述对象)),创造一个继承a对象的新对象,返回的新对象的原型就是a,a不可省略
创造一个空对象的方法:
var a = new Object();
var a = Object.create({})
var a = Object.create(Object.prototype);
a.isPrototypeOf(b)a是不是b的原型对象
a.__proto__可以用来改写一个对象的原型对象,这是一个浏览器才部署的内部属性,最好不用
有 3种方式获取原型对象,1, obj.__proto__ 2.obj.constructor.prototype3. Object.getPrototyeOf(obj)
只有第三种最可靠
继承
构造函数的继承
第一步:
子类的构造函数内,调用父类的构造函数
function super(){}
function super1(){}
function sub() {
super.call(this)(如果要多重继承,则可在写 super1.call(this),但是第一步只能指向一个,只能是一个的实例,即原型对象只能有一个,但是可以继承多个构造函数)
}
或者
function sub(){
this.base = super;
this.base()}
第二步:
sub.prototype = Object.create(super.prototype);
sub.prototype.constructor = sub;
单线程模式
js是单线程的,同一时间内只有一个线程在运行,但是可以是异步
Event Loop消息队列,一轮一轮地执行消息队列的线程,即回调函数
定时器,
正常任务 (settimeOut,setInterval,setmmediate,I/O,各种事件(比如鼠标单击事件))是在下一轮Event Loop执行,比如setimeOut(function(){},0)实际并不是立即执行,微任务(主要是promisehe process.nextTick),在这一轮任务都结束之后执行,比如Promise,所以执行任务,后执行Promis,在执行setTImeout
js异步执行的方式:
1,回调函数
2,事件监听,
3,发布/订阅,(观察者模式),先订阅,那个事件发生了就执行,之后某个动作触发了这个事件,
Promise是一个对象,目前Es6已经支持,是按同步的思路实现异步
var promise = new Promise(function(resolve, reject){
if() resolve(value);
else reject(value)
})
调用:
promise.then(f1(value),f2(value))f1代表成功时的回调,f2代表失败
promise.then(f1,f2).then(f3,f4),成功之后执行f1,并且f1也成功,才执行f3,如果f1失败执行f4
promise.then(f1).then(f2).then(f3,f4),执行失败或者f1,f2,当中任意一个失败,都执行f4
promise.then(f1).catch(f2),执行失败,或者f1失败,都会执行f2
DOM模型(document Object Model)文档对象模型,一个的对象,dom的标准: DOM3
节点( Node):对象,是最小单位
节点有几种类型(也可以说是 3种,元素节点,文本节点,属性节点)
1. document 整个dom树的顶层节点,代表整个文档,文档最高一层是html节点(树的根节点),nodeName: #document, 9,注意Document是个构造函数,document是个对象有nodeName属性
2.DocumentType: doctype标签(比如)nodeName: 等于DocumentType.name, 10
3.Element: 元素节点,就是一些标签 ,nodeName大写字母,比如HTML,1
4.Text 文本节点 #text 3
5.Attribute属性节点 属性名,比如id 2
6.Comment注释 #comment 8
7.DoucmentFragment,存在于文档中,但是还没被插入到dom树里,处于游离状态, #document-fragment, 11
节点的属性:
nodeName如上
nodeType如上
nodeValue(只有属性节点,comment节点,xml文档的cdata节点(不知道是什么)有,其他一律返回null)
textContent 返回当前节点和后代节点的文本内容,会把文本(不高考comment节点的)提取出来放在一起(只会提取文本),可读写,读的时候回忽略标签,写的时候会把字符串的标签进行转义,变成文本。text节点和Comment节点的值等于nodeValue,document节点和doctype节点返回null,如果要读整个文档的,用
document.documentElement.textContent
baseURI 任何节点一般都一样的,都是当前网页的url地址(绝对地址)有window.location决定,可通过标签进行改变,
节点的属性: ownerDocument,顶层文档对象,就是document对象,docuement对象的这个属性返回null
nextSibling 返回后面第一个同级节点,包括文本节点和评论节点
previousSibling 前面
parentNode父节点(只能是元素节点,document节点,documentfragment节点)
parentElement父元素节点,
childNodes子节点(不包含子孙节点哦),是一个nodeLIst集合,这时时动态的 firstChild,lastChild第一个和最后一个子节点
节点对象的方法
a(节点),把一个节点插入到子元素的最后一个位置,如果是一个已存在dom的节点,就转移到新的位置,不是克隆
hasChildNodes(),是否有子节点,
cloneNode(布尔值(true,克隆子孙节点,false,默认不克隆子孙节点))返回一个新的节点,属性都一样,但是事件没有克隆
a.inserBefore(b节点,a的子节点c)(有问题),把b插入到a的子节点c的前面,返回新的b节点,如果c为null,则插入到最后
如果要插入到后面,可用 parent.insertBefore(s1,s2.nextSibling);
removeChild(子节点)移除子节点
replaceChild(new, old),返回old节点
b.cotains(a)b是否包含a, 注意a.cotians(a)返回true
a.compareDocumentPosition(b)返回a和b的位置关系(还不是很理解)
isEqualNode(),返回是否相等,类型相等,属性相等,子节点相同
normalize(),去除空的文本节点,把比邻的文本节点合并成一个,
节点集合对象
NodeList对象,是个类数组对象,NodeList是构造函数,可能是静态页可能是动态的,
querySelectorAll,静态
ChildNode动态
遍历的最好方法是 for循环,和for( of)不要用for..in,会把length和item返回也遍历了,而且 不保证顺手
NodeList.item(index)=NodeList[index]
HTMLCollection对象,类数组,都是动态的,只能是节点元素,可以通过id和name获取,比如forms.id=forms.name=forms.item(index)=forms[index]
document.links,document.forms,document.images,
ParentNode接口
a.children 返回一个htmlcollection集合,包括所有子元素节点(不包括子孙),和childNode不同,后者又包含其他类型的节点
firstELmentChilid,lastElementChild,注意document节点的都是html节点
childELementCount子元素节点数量
ChildNode接口
remove()删除自己
before(),在自己前面插入一个同级节点,可插入文本节点,(有问题)
after(),(有问题)
replaceWith,(有问题)
document节点
window.document = document = 节点.ownerDocument
对于 iframe iframe.contentDocument
ajax返回的文档,用 XMLHttpRequest对象的 responseXML
内部属性:
1.doctype 对象,等于document.fistChild包含文档类型信息,对于html5,就是
document.doctype ""
document.doctype.name "html"
2.documentElement 文档的根节点,对于html文档就是html节点
3.defaultView,在浏览器中等于document对象所在的window对象,
4.body,head
5.activeElement文档中获得焦点的元素
.集合属性
document.links 所有设置href的a元素和area元素
.forms
.images
.embeds所有embed元素
.scrips 所有script元素,也是htmlcollection集合
.styleSheets 所有style元素,类数组对象,每个元素都有一个一个cssRules对象,代表这个样式表的样式信息
信息属性
documentURI 网址, URL也是,但是后者只有htlm文档具有,他们都是静态的,文档大锚点变化,他们不会变,但是location会变
domain域名 二级域名下,可以吧该值设置为一级域名
lastModified最后修改的时间戳,字符串,用Date.parse()转化成时间戳格式才能比较
location 对象,底下有属性
document.location.href // "http://user:passwd@www.example.com:4097/path/a.html?x=111#part1" document.location.protocol // "http:" document.location.host // "www.example.com:4097" document.location.hostname // "www.example.com" document.location.port // "4097" document.location.pathname // "/path/a.html" document.location.search // "?x=111" document.location.hash // "#part1" document.location.user // "user" document.location.password // "passed
方法:
// 跳转到另一个网址 document.location.assign('http://www.google.com') // 优先从服务器重新加载 document.location.reload(true) // 优先从本地缓存重新加载(默认值) document.location.reload(false) // 跳转到新网址,并将取代掉history对象中的当前记录,再点击后退,不会回到当前页面 document.location.replace('http://www.google.com'); // 将location对象转为字符串,等价于document.location.href document.location.toString()
location=新地址(可以是相对地址)相等于对location.href,调到一个新的网址
location='#top'锚地,跳到锚点
其他属性
document.referr,访问来源,如果是直接输入,返回空字符,于http头信息referer保持一致,
.title标题
.characterSet字符集,比如UTF-8, ISO-8859-1
.readyState,当前文档状态,loading加载html代码,尚未解析完,interactive加载外部资源中,complete加载完成
浏览器渲染过程:解析 html文档,loading,遇到script元素,并且没有async和defer属性,暂停解析,开始执行脚本,loading,解析完成interactive,等待加载外部文件,完成complete
.designMode是否可编辑,打开赋值为'on'
.implementation(接口(字符串),版本号(字符串))判断是否部署了某些dom接口
.compatMode兼容模式,一般设置了明确的DOCTYPE,都返回CSSCompat(严格模式),还有一种是BackCompat(向后兼容模式)
.cookie cookie信息
读写方法:
document.open(),write(),不会把标签转义,打开一个新的文档,等于清理了当前的文档,然后用write写,close关闭,关闭后就不能在write了,如果解析完成(DOMContendLoaded事件之后),在用write,会先调用open,把页面所有都清掉,之后的每次write只会追加,除非又用了close,这些都是老古董的方法,最好不要用
查找节点的方法
document.querySelector,
querySelectorAll
参数都是按 css选择器,但不支持css伪元素(比如:first-line)和伪类的选择器(:link,:visited),这两个也是元素节点的方法
getElementsByTagName(),返回htmlcollection对象,大小写不敏感,也是元素节点的方法
getElementsByClassName(), 返回如上,正常模式,大小写敏感同时符合多个用'foo bar'同时符合foo和bar类,次序不重要,也是元素节点的方法
getELementsByName nodeList对象,
getElementById大小写敏感,比querySelector高效,只是document的方法,
elementFromPoin(x,y)返回位于页面指定位置的最上层的元素节点
生成节点的方法
document_createlement('div')大小写不敏感
creatTextNode('hellodowew')会转义<>,但是不会转义引号
createAttribute(name) 通过生成对象的value属性赋值
var node = document.getElementById_x_x_x_x_x_x_x_x_x_x_x("div1"); var a = document_createAttribute("my_attrib"); a.value = "newVal"; node.setAttributeNode(a);
等于
var node = document.getElementById_x_x_x_x_x_x_x_x_x_x_x("div1");
node.setAttributeNode('my_attrib', 'newVal');
createDocumentFragment()
事件相关方法
creatEvent(事件类型) Event, UIEvents、MouseEvents、MutationEvents、HTMLEvents都可以,用字符串
新建事件的流程:
var e = document_createEvent('Event');
e.initEvent('build', true, true);
document.addEventListener('build', function(e){}, false);
document.dispatchEvent(e)
其他方法
hasFocus()当前文档是否有元素获得焦点
...其他方法不太常用
Elment节点
属性:
.attributes类数组对象,所有属性节点,动态的
.id .tagName
.innerHTML 内容, 如果文本节点中包含&、小于号(<)和大于号(>),innerHTML属性会将它们转为实体形式&、<、>会转义,所以插入script不会执行
outerHTML包括自身的
className class名
classList 类数组对象,每个属性都是类名,有这些方法,add(类名1,类名2...),remove(),toggle(true为添加,false为删除),cotains(),item(index)第index类名 ,toString()相等于className
盒子模式
详见照片
一些总结
整张页面,
当没有水平滚动条是 (这里不能用body的clientHeight)
document.documentElement.clienHeight === windows.innerHeight(包括滚动条)
如果元素没有溢出 scrollHeight === clientHeight
如果元素滑到底部
e.srcollHeight-e.scrollTop === e.clientHeight
如果元素没有溢出, offsetHeight 比clientHeight多了边框
整张网页的高度和宽度,可以从document.documentElement(即元素)或 元素上读取。 // 网页总高度 document.documentElement.offsetHeight document.documentElement.scrollHeight document.body.offsetHeight document.body.scrollHeight // 网页总宽度 document.documentElement.offsetWidth document.documentElement.scrollWidth document.body.offsetWidth document.body.scrollWidth 由于和的宽度可能设得不一样,因此从上取值会更保险一点。 视口的高度和宽度(包括滚动条),有两种方法可以获得。 // 视口高度 windows.innerHeight // 包括滚动条 document.documentElement.clientHeight // 不包括滚动条 // 视口宽度 windows.innerWidth // 包括滚动条 document.documentElement.clientWidth // 不包括滚动条 某个网页元素距离视口左上角的坐标,使用Element.getBoundingClientRect方法读取。 // 网页元素左上角的视口横坐标 Element.getBoundingClientRect().left // 网页元素左上角的视口纵坐标 Element.getBoundingClientRect().top 某个网页元素距离网页左上角的坐标,使用视口坐标加上网页滚动距离。 // 网页元素左上角的网页横坐标 Element.getBoundingClientRect().left + document.documentElement.scrollLeft // 网页元素左上角的网页纵坐标 Element.getBoundingClientRect().top + document.documentElement.scrollTop 网页目前滚动的距离,可以从document.documentElement节点上得到。 // 网页滚动的水平距离 document.documentElement.scrollLeft // 网页滚动的垂直距离 document.documentElement.scrollTop 网页元素本身的高度和宽度(不含overflow溢出的部分),通过offsetHeight和offsetWidth属性(包括Padding和Border)或Element.getBoundingClientRect方法获取。 // 网页元素的高度 Element.offsetHeight // 网页元素的宽度 Element.offsetWidth
盒子模式到此结束
相关节点属性
.children , .childElementCount, firstELmentChild, lastElementChild,nextElementSibling,PreviousELementSibling
offsetParent 返回最靠近节点的position不为static的元素节点,如果所有上层节点都不符合,就返回body,
关于属性的: getAttribute(),setAttribute(),hasAttribute,removeAttribute()
查找节点的: querySelector,querySlectorAll,(前面两个都是全局搜索,然后在匹配css查找器)getElementsByTagName,getElementsByClassName(后两个都是在当前范围内搜索)
closest(css选择器)返回最接近当前元素,并且符合css选择器的父元素,包括自己,所以会先在自己上判断是不是符合,然后在往上,如果自己符合就返回自己
matches(css选择器)判断自己是不是符合css选择器,带兼容前缀,
matches || webkitMatchesSelector || mozMatchesSelector || msMatchesSelector
事件相关的: addEventListener,removeEventListener,dispatchEvent
其他方法: scrolllntoView(true顶部重合,false底部重合)把当前元素滚到可见区域
Element.getBoundingClientRect()返回一个对象,提供盒子模式信息,返回的是相对于视口的值,都是从边框外计算的,所以都包括border和padding,(可能有滚动条,未证实)所以不是绝对的值,会随着滚到条变化,绝对的值要加上window.scrollX或者document.documentELement.scrollLeft
getClientRects(),返回一个类数组对象,表示元素在页面所有形成的矩形(块元素只有一个,但是行内元素会有多个)
element.insertAdjacentHTML(position, text);解析HTML字符串,然后将生成的节点插入DOM树的指定位置
位置有四种:
beforebegin:在当前元素节点的前面。 afterbegin:在当前元素节点的里面,插在它的第一个子元素之前。 beforeend:在当前元素节点的里面,插在它的最后一个子元素之后。 afterend:在当前元素节点的后面。
例子:insertAdjacentHTML('afterend', '
two
');
remove(),移除当前节点
focus()聚焦
属性节点
e.attributes['id']== e.id(只有标准属性) ==e.getAttribute('id') ==e.attributes[index] ==e.attributes.id
js对象的属性是大小写敏感的,但是html是大小写不敏感的,所以用对象的方法获取属性一律小写,并用骆驼写法,一些保留字要注意
class=>className
for=>htmlFor
dataset返回data-属性名,属性名只能包括小写字母 数值 - . : _
不能写成 data-helloWorld 要写成data-hello-world,获取是dataset.helloWorld
文本节点
创建: document_createTextNode(文本字符串) 相当于 new Text(文本字符串)
属性:
data 等于nodeValue
wholeText返回与当前节点相毗邻的文本节点
length文本字符串的长度
nextElmentSibling
previousElementSibling
方法:
appendData()追加文本
deleteData(开始位置,长度)
insertData(插入位置,字符串)
replaceData(替换开始位置,长度,字符串)
subStringData(开始位置,长度)返回一个字符串,原来的不变
remove()删除自己
splitText(分割位置)如果参数是3,原来变成0,1,2,返回3,4...与element.normalize()相反
DocumentFragment游离的一个dom片段
创建:
createDocumentFragment() 等于 new DocumentFragment()
一旦被加入到 dom树中,他自身就变成空了,可以再次被利用,如果要保存可以用cloneNode(true)复制一个
属性:
children,fistElmentChild,lastElmentChild,childElementCount
事件监听:
document,element,window都有这个接口
添加
addEventListener(事件名(大写敏感),回调函数,布尔值(默认fasle,冒泡时触发,true捕获是触发)),可以多次执行为同一个事件添加多个回调函数,按顺序,
removeEvenListener(同以上) dispatchEvent(Event对象(不能为空)),返回一个布尔值,如果回调函数用为了event.preventDefault(),才返回false
使用方法:
para.addEventListener('click', hello, false); var event = new Event('click');
para.dispatchEvent(event);
自定义事件方法:
var event = new Event('build'); elem.addEventListener('build', function (e) { ... }, false); elem.dispatchEvent(event);
另外一种:
var myEvent = new CustomEvent("myevent", { detail: { foo: "bar" }, bubbles: true, cancelable: false }); el.addEventListener('myevent', function(event) {}); el.dispatchEvent(myEvent);
ie的方法:(不支持各个事件类型的构造函数,不能用new Event)
var event = document_createEvent('Event'); event.initEvent('build', true(是否冒泡), true(是否可取消),对象额外信息); document.addEventListener('build', doSomething, false); document.dispatchEvent(event);
监听函数就是回调函数方式为:
1.html形式 on- load click 后面是可以执行的代码,不是函数,所以是 函数名()的形式
2.ELment节点事件属性(只能在冒泡触发)
window.onload = 函数名,
3.addEventListener()
回调函数的 this
addEventListener方法 总是指向监听回调函数并且执行函数的那个节点
on- 如果是函数,不会指向触发节点,指向全局,所以一般吧代码直接写在里面
指向触发节点的方法:
// JavaScript代码 element.onclick = print element.addEventListener('click', print, false) element.onclick = function () {console.log(this.id);} // HTML代码
事件传播
捕获(一次) -目标(刚捕获一次,要冒泡又一次)-冒泡(一次)
window-document-html-body-...-目标-目标-...-body-html-document-window
事件代理
由父节点监听事件,统一处理子元素的事件,
停止冒泡: even.stopPropagation()只会停止当前回调函数的传播,不会禁止相同事件的其他函数的传播,如果都不想了可以event. stopImmediatePropagation
Event对象
new Event(事件名,{bubbles: 是否冒泡,默认false,cancelable: 是否可以取消,默认false})
属性:
bubbles 返回是否冒泡
eventPhase,事件传播情况,0没法说,1捕获阶段,2目标阶段,3.冒泡阶段
cancelable 是否可取消
defaultPrevented 是否调用preventDefault
currentTarget 事件所在的节点,执行监听函数的节点,tartget(ie8以下,是用srcElement)事件发生的节点,一般是最底层的元素,如果是事件代理,currentTarget就是父元素指向this对象,target就是子元素
type 事件名,返回字符串
detail事件对应得某些信息,比如dbclick,detail总是2
timeStamp毫秒时间搓,事件发生的时间
isTrusted是否为真实用户触发
方法:
preventDefault()传播的各个阶段不执行默认行为
stopPropagation() stopImmediatePropagation()
事件的类型
鼠标事件:
mousedown-mouseup-click-dbclick
mouseover在元素里面移动是一直触发
mouseenter只触发一次,进入元素的时候触发
mouseout出去触发,会冒泡
mouseleave出去是触发,不会冒泡
contextmenu点击右键
MouseEvent对象继承event对象和uievent对象
new MouseEvent(事件名(以上那几种),初始化对象)
属性:
是否按下
altKey
ctrKey
metaKey
shiftKey
按下哪个键:
button: -1没有按下,0主键,1辅助键,2次键
buttons 返回十进制数(可转化为3位的二进制,个位表示左键,十位表示右键,百位表示辅助键 111(7)同时都按下)
位置:
clientX,clientY相对浏览器 screenX,screenY相对屏幕
movementX,moveMentY相对前一个位置的相对位移
relatedTarget次要 相关节点
wheel事件,鼠标滚动事件,继承mouseEvent
new WheelEvent(同上)
属性:
deltaX水平滚到量
delatY 垂直。。。
delatZ z轴。。。
delatMod单位 0像素,1行,2页
键盘事件
new KeyboardEvent,继承mouseEvent
keydown - keypress(除了alt,Ctrl、shift,met) -keyup
用户不松口顺序
keydown
keypress
keydown
keypress
。。。
keyup
属性:
是否按下的部分同 mouseEvent
key:键名
charCode 键的Unicode值,只有keypriess有,其他两个没有
进度事件:
new ProgressEvent()
abort 进度被终止,不包括发生错误被终止
error 发生错误无法加载(最好反正html上以onerror的形式),不会冒泡
load 成功加载结束
loadstart 开始加载
loadend 进度停止,error/abort/load后面
progress 经常中
timeout超时触发
属性: lengthComputable,是否可以计算进度
total 进度总长度
loaded 已完成长度
拖拉事件
。。。暂时不总结
触摸事件
Touch对象,触摸点
属性:
identifier 实例的唯一标识
screenX,Y,
clientX,y,
pageX,y(相对窗口的绝对位置,考虑到滚动条)
radiusX,y影响范围,椭圆的长轴和短轴
radiusAngle椭圆旋转角度,0-90度
force 压力,0没有压力,1有压力
target,触发节点
TouchList
比如三个手指触摸,就有三个 touch对象
TouchEvent对象,是个事件对象
是否按下:
同上
changedTouches返回一个touchlist对象,当前触摸事件引发的所有Touch对象
情况如下:
touchstart被激活的触摸点,
touchmove发生变化的触摸点
touchend消失的触摸点
targetTouches 返回一个touchlist对象,包含目标节点里面所有处于激活的触摸点
touches 返回touchlist对象,包含所有处于活动状态的触摸点
触摸事件:
touchstart
touchend target对象和touchstart的一样
touchmove 。。。。。一样
touchcancel触摸点取消
表单事件
input事件,input,textarea值发生变化时触发,会连续触发,没按下一个键就触发
select事件,input,textarea选中文本时
change input,textarea值发生变化并且丧失焦点时,,select完成选择,激活radio,checkbox,不会连续触发
reset
submit 发生的对象是form不是某个button
文档对象 window、body、frameset对象
beforeunload 窗口将要关闭,如下可弹出对话框,在关闭之前
window.addEventListener('beforeunload', function (e) { var confirmationMessage = '确认关闭窗口?'; e.returnValue = confirmationMessage;(非空的值就可以) return confirmationMessage; });
unload 发生在beforeunload和pagehide后面,如果用户是按下前进后退是不会触发的,所有资源依然存在,但是对用户不可以见,如果在window上定义了这个事件,则不会缓存页面
load成功加载(除了从缓存中加载),
error
pageshow 加载成功时触发,包括第一次和缓存加载,排在load后面,属性event.persisted,true表示缓存加载,
pagehide persited设为true则保存在缓存中,发生在unload之前
load-》pageshow-》pagehide-》unload
DOMContentLoaded事件(ie8不支持)
文档解析完毕,外部资源还没下载结束,比 load早很多在document对象触发
readystatechange发生在document和xmlhttpReques对象上,当readyState发生变化时触发
scroll事件,window上,会连续触发, 用requestAnimationFrame和settimeout可以限制触发事件的频率(不是很理解。。。)
resize事件,发生在window,body,framset
haschange事件,window对象,在url hash值变化时,
popstate事件 history对象发生显示切换的回收,只有点击前进后退,或者history.back(),history.forward,go()时才触发,
焦点事件 document对象和element对象
focus不会冒泡
blur失去焦点,不会冒泡
focusin 将要获得节点,会冒泡,fierfox不支持
focusout 将要死去焦点,同上
属性:
target 和relatedTarget,(foucs和blur为null)
css操作:
元素节点有个style对象,表示元素的行内样式,不包括 外链样式和内嵌
设置样式的方法 (主要是设置行内样式)
1。el.setAttribute('style','')
2. 通过style对象
类似 style.backgroundColor='#000'的方法,注意这种方法要用骆驼表示法,并且要写单位,并且不能用margin这种简写,style对象有一个cssText属性返回样式的字符串,
通过
typeof el.style.样式名 === 'string'可以判断是否支持这个样式,如果行内样式没设置,也会返回一个空字符串,但是如果不支持,会返回undefined
判断函数:
function isPropertySupported(property){ if (property in document.body.style) return true; var prefixes = ['Moz', 'Webkit', 'O', 'ms', 'Khtml']; var prefProperty = property.charAt(0).toUpperCase() + property.substr(1); for(var i = 0; i < prefixes.length; i++){ if((prefixes[i] + prefProperty) in document.body.style) return true; } return false; } isPropertySupported('background-clip') // true
style对象的方法:
setProperty(name, value)
getPropertyValue(name)
removeProperty(name)
window.getComputedStyle(元素节点, 伪元素(可省略,':before',':after',‘:first-line’,‘:first-letter’))返回节点最终的样式,包括外链样式和内嵌的效果,返回的单位有带px,颜色是rgba格式,不能用简写,只能读不能写
有一个方法 getPropertyValue(name),同style对象的方法
伪元素:
不能用style对象读取,只能用 window.getComputedStyle读取
StyleSheet对象代表一张样式表,包括外链和内嵌
1.document.styleSheets类数组对象,返回页面的所有样式表
2.通过link和style节点的sheet属性可获取他们对应的stylesheet对象
link节点.sheet
stylesheet的属性
1.media media.mediaText ‘screen’用于屏幕,‘print’打印,‘all’两者都适用
2.disable可读写,赋值为true或者‘disabled’代表关闭一张样式表
3.href 内嵌返回null
4.title
5.type 一般为text/css
6.parentStyleSheet 返回样式表中通过@import外部导入的样式表,没有返回null
7.ownerNode,所在dom节点,一般是link或者style节点,如果是被其他样式引入的,则返回null
8.cssRules,类数组对象,代表每条css规则
document.querySelector(link节点).sheet.cssRules[0].cssText // "p { line-height: 1.4em; color: blue; }"
document.querySelector(link节点).sheet .cssRules[0].style.color = 'red';
原教程链接: http://javascript.ruanyifeng.com/
let's go!
1. var a=1; 效果类似a=1,区别在于前者可用delete删除,后者不可
2.变量只声明,但未定义,值就为undefined,表示无定义,
此处啰嗦下 undefined 和null 的区别,可见http://www.ruanyifeng.com/blog/2014/03/undefined-vs-null.html,
undefined就是未赋值,缺少值,应该要有值,但是却没定义,比较多情况
null 没有对象,不应该有值,主要注意null作为原型链的终点,Object的原型对象的原型对象就是null,null没有原型对象了,终结,
Object.getPrototypeOf(Object.prototype) //
null
undefined == null //true
Number(null) 0
Number(undefined) Nan
3.关于变量提升,js引擎的工作方式是先解析代码,获取所有被声明的变量,然后在一行一行运行,导致会存在变量提升的现象,会把用var命令声明的变量提升,
console.log(a);var a= 1; 结果是undefined, 其实是这样运行的: var a; console.log(a);a=1
4.es5的区块不作为作用域,和es6的区块作为作用域不同
5.switch 的参数和case 比较是用===严格相等运算符,所以不强制发生类型转换,
6.感觉不重要,但还是记下,标签,
top:
for (var i = 0; i < 3; i++){
for (var j = 0; j < 3; j++){
if (i === 1 && j === 1) break top; //或者continue top
console.log('i=' + i + ', j=' + j); } }
7.js中的数据类型,主要有:字符串,数字,布尔值/(前面三个都叫原始数据类型),对象(函数,数组,狭义对象),null 和undefined
8.通过三种判断方式可以判断数据的类型
1.typeof 数据(先学这个) 2,数据 instanceof 对象 3,Ojbect.prototype.toString()
typeof 结果,记住结果返回的都是字符串
原始类型:字符串 string 数字 number 布尔值 boolse
合成类型(对象)
{} object
[] object
以上两种可以进一步通过 数据 instanceof Array ——》false 不是数组,true 是数组来区分
null
null object(不能说明null是对象,因为历史遗留原因而返回object)
undefined
返回undefined,关于undefined有个使用方法,typeof undefined并不会报错,可以用来判断某个变量没有声明(并非没定义,没定义直接可以用===undefined判断),
错误做法 if(v)报错, 正确 if(typeof v === "undefined")
9.关于布尔值,除了undefined, null, false, 0, NaN, ""或者''(空字符串)会转化为false,其他都是true,包括[]和{}空数组和空对象
10.关于数值,js浮点数按64位二进制存储,
第一位 符号位,0 + 1 -
2-12 : 指数部分
13-64: 小数部分
(精度):有效数值第一位默认为1,但是不存在64位中,所以有52+1个二进制位表示,所以-(253-1)到253-1 个整数可以精确表示
(数值):指数部分长度为 11,所以数值范围21024到2-1023 ,
指数部分如果超过 1024,js会返回Infinity,如果小于-1023,js会返回0;
特殊数值 -0 === +0, 0 === -0, 0 === +0
( 1 / +0)Infinity (1/-0) -Infinity
NaN:非数值,用isNaN判断,0/0 NaN NaN === NaN /false(是js里面唯一不等于自身的值)
Infinity,无穷大,isFinite判断是不是正常值,NaN和Infinity都返回false,
11.字符串,其实字符数值,一些数值的属性都可以用,比如length,比如a[0]可以返回第一个字符(2个字节,16位utf-16格式储存,也是unicode形式储存,)但是不能改变字符串的字符,有charAt(i)返回i位的字符,charCodeAt(i)i位字符的unicode值
Base64编码方法,把任意字符转化为可打印字符,btoa() 转化为base64,atob()还原编码,
只能直接转化 ASCII码,如果转化非ASCII码值,要先这
样 btoa(encodeURIComponent(str)),decodeURIComponent(atob(str));
encodeURIComponent不会对ASCII字符和数值以及_ -.! ~*()编码,其他都会变成一个或多个十六进制的转移字符替换
12.对象,三种生成方式,
1.var a={}
2.var a = new Object();
3.var a = Object.create(Object.prototype)
对象的引用是地址拷贝, var a1 = {}, a2 =a1, a2.a=1, a1.a就等于1,如果变成原始数据类型,就只是值拷贝;
({foo:123})行首如果是大括号,加上()之后就是代表对象,不然只是个代码块
读取不存在的键不会报错,会等于 undefined,
tips: 'a' in window来判断一个变量是否声明过
Object.keys(o)返回一个包含键明的数组,delete 键名可以用来删除属性(存在和不存在都会返回true,除非某个属性的configurable=false,才会返回false,还有也不能删除继承的属性,但是这是返回true,也不能删除 var 命令声明的变量,)
for(var i in o)可以遍历全部可以遍历的属性,跳过不可遍历,不跳过继承的属性,用o.hasOwnProperty(key)可以用来判断是不是自身属性
13.数组,是一种特殊的对象typeof返回object,键名是序列数,可以用Object.keys(arr),返回序列数值的数组
可以添加数值,但是健名一定要是可以转化为整数的值,添加后有效, length改变,
in 字符串可以用在对象也可以用在数值,如果某个位置是空位,返回false ,arr[100]=1, 之前的100个键名都返回空,
for(in)会遍历非数字建值,虽然这个建值并且没有算入length中,也不会返回,一遍遍历用for(),while
delete删除元素,不会影响length,只是变成undefined
关于空位 [, , ,]length是2,最后一个逗号后面如果没有成员,忽略,for in ,foreach, keys()都会过滤掉空位,但如果是[undefined,undefined,undefined]就都不会过滤
14.函数,
函数声明的方式:
1.function 命令声明(存在变量提升,会声明和赋值)
function a() {}
2.表达式,把一个匿名函数赋值给一个变量
var print = function() {};
3Function 构造函数,
var add= new Function(x,y,'return x+ y'),总是把最后一个参数当做函数体,
属性,
f.name,
1.function f1(){} f1.name /f1
2.var f2 = function() {} f2.name /f2
3 var f3 = function myname(){} f3.name /myname(只在函数内有效)
f.length 返回定义时的参数个数,不是调用时的参数个数,arguments.length就是调用时参数的个数
f.toString()返回源码
参数,如果参数是原始类型,就是传值传递,如果是对象,数值,或其他函数就是传地址传递,修改他的属性会生效,但是注意若干把对象整个改了,就切断来了地址,也不会影响到原来的了,如果要改,可以利用 window对象进行传地址
arguments函数参数,是个类数组对象,通过Array.prototype.slice.apply(arguments)可以转化成数组
闭包,一个声明定义在另一个函数体内的函数,因为函数存在作用域概念,所以可以通过闭包读取函数内部属性,还有要注意的是闭包的作用域是在他声明的函数体内,而不是调用时的,闭包还有个作用是保存他声明定义时的状态
例子:
function createIncrementor(start) { return function () { return start++; }; }
var inc = createIncrementor(5);
inc() // 5
inc() // 6
inc() // 7
立即执行函数
js规定function放在行首,都代表函数的声明,所以后面不能跟(),表示执行,所以立即执行函数的形式有两种
1.(function(){}()); 2(function(){})();
主要用 ()把声明变成表达式,也可以用其他运算:
var i = function(){}(); 不把function放行首
true && funcition(){}();
0,function(){}
!function(){}();
+
-
~
eval_r()执行字符串,没有自己的作用域,作用域是当前(不推荐用),即使是间接调用
var a = 1;
function f() { var a = 2; var e = eval; e('console.log(a)'); }
f() // 1
15运算符
+ a + b
1,如果a或者b是对象,先执行valueOf(,一般对象会返回原对象),如果结果是对象,就执行toString,(一般对象结果是返回字符串[object, Object],),但两个运算子有一个是字符串的时候,都转化为字符串,进行拼接运算,如果都是数值,就进行数学运算,只有加法会这样麻烦,如果其他运算符,比如减肥,乘法,都直接转化为数值进行运算(使用Number),
数值运算符 : +a, 会把a变成数值, 负数值运算符(结果变成负数而已)
2比较运算符,如果都是字符串,按字典顺序(实际是unicod吗点),否者其他原始类型数据都转化为数值,如果是对象,对象的方式跟加法的一致,
严格相等 ===
不同类型马上 false,如果是同一类型的原始数值,值相同就true,
注意 NaN ===NaN false
同一类型的复合型值,比较的是地址,是否指向同一个对象,如果是其他比较运算符,比较的是值,
相等 ==
会进行强制转化
原始类型的数据会直接变成数值进行比较,即用 Number()
对象和原始类型比较,对象转化为那个原始类型,进行比较
undefined和null和其他类型的值比较都是false,但是undefined· == null true
void 表达式, 执行一个表达式,并返回undefined,
强制转化类型:
1Number, 如果是字符串,布尔值,null,undefined,变成数组或者NaN(例如'324abc',如果用parseInt('311abc')会变成311, ''->0, undefined-> NaN, null-> 0 ),Number会自动去掉之前和之后的空格
如果是对象型的复合数据类型,一律返回 NaN
步骤是: 对象: 先用valueOf判断是不是返回对象,如果是先调用对象的toString(),如果返回的还不是原始类型的值,就报错,如果是的话就直接对返回值使用Number,
自动转化为数值的情况,数值运算符,除了加法以为的算术运算符
2.String()对象的转化规则是,先toString(),再valueOf,纯对象变成"[object Object]",数组是"1,2,3"
3.Boolean(),除了 undefined,null, -0,+0,0,NaN,''为false,其他都为true,
16错误机制,
Error对象的派生对象: SyntaxError,解析是出错,ReferenceError,undefined错误,RangeError,超出有效范围,TypeError,不是预期类型,比如new 123这种,URIError,Uri函数相关参数不对的情况,这些函数主要有encodeURI()、decodeURI()、encodeURIComponent()、decodeURIComponent()、escape()和(),
EvalError,eval执行时抛出错误
自定义错误方法:
function myError(mess){this.message = mess ||''}
myError.prototype = new Error();
my.prototype.constructor = myError;
new myError('my error');
throw用来抛出一个错误对象,也可以是其他数据
try{
throw new Error(1);
不会执行;
} catch{
2
return 4/throw 4(第一个return被finally的覆改掉,但是return或者throw会执行,只是返回的时候要等finally的执行完才返回)
}finally
3
return 4
不会执行
}
不会执行(因为 return了)
如果没有 catch,会执行finally,但是不会执行后面这个模块之后的代码了
语法:
1对象:用new Object(a)===a (如果a是对象) true
如果 a是原始数据类型,则变成对应的对象,数值->Number对象,字符串->String, 布尔值-> boolean
对象的属性: 1.Object对象的静态方法,只能通过Ojbect对象调用,不能被继承,主要有Object.keys()获取对象的属性键名,并且返回数值,只遍历可遍历的自身属性,不包括继承的,Object.getOwnPropertyNames(),跟前者有点像,只是他可以遍历不可遍历的属性,比如数值的length,
Object.getPrototypeOf(),获取对象的Prototype对象,
实例方法
valueOf(),一般对象返回对象本身,
toString() ,每个值都有一个toString方法,返回不一样的东西,但是通过Object.prototype.toString.call(),可以返回类型,比typeOf更加精细
2Array对象
var arr = new Array(2) 可以不用写new() [undefined,undefined] 0 in arr /false,虽然每个元素是undefined,但是,不能得到键名,Array会因为参数的不同而结果不同,比如new Array(1,2) 就等于[1,2]
Array的静态方法,isArray()判断是不是数值, typeof 数值,返回的是object
实例方法, valueOf()返回数值本身,toString,'1,2,3'字符串
push(1,2,3)在数值后面推入三个数,如果参数要是数值,可以用Array.prototype.push.call(a,b)其中a和b是数值,也可以用a.push.call(a,b),该方法也可以应用到对象,添加后对象变成类数组对象,[].push.call(a, 2), 其中a={a:1},运行后,a变成{a:1,0:2,length:1},length取决于数字键名,
pop()删除最后一个元素,并返回删除元素,空数组pop,返回undefined,不会报错,
pop和push 体现了栈,后进先出
shift(),删除的是第一个元素,unshift()在第一个位置添加元素,reverse(),颠倒元素位置
splice(删除起始位置,删除个数,之后要在删除位置加入的元素),第一个元素如果是负数代表倒数,如果只传一个参数,代表把数组变成两部分,把起始位置之后的元素删掉
var a = [1, 1, 1];
a.splice(1, 0, 2) // []
a // [1, 2, 1, 1]
sort(),按字典排序(10111排在111前面)可以传一个函数参数,function(a,b){return a-b},返回值大于0就按ba从小到大
join(s), 返回一个用字符s隔开的字符串,如果元素是undefined,null,或者空位,会变成空字符
[undefined, , null].join('#') ‘#’
通过 Array.prototype.join.call('ab', '-') /a-b,因为字符可以算是字符数值
或者类数组对象也可以, obj={0:1, 1:2,length:2} 执行后变成1-2
[1].contact([2,3],[4])/[1,2,3,4]返回一个连接两个数组的新数组,等于(2,3,4),如果没有传参数,则返回的是她本身的浅拷贝,即引用,如果元素是复合型的值,新值拷贝的就是引用,改变会生效
slice(其实位置,结束位置后一个位置(可省)),返回这样一个部分,如果参数是负数,就是倒数
一个重要的用法就是把类数组对象变成真正的数组, Array.prototype.slice.call(obj)
[].map(function(v,i,arr){return},arr)会返回一个数组,map的第二个参数代表函数this的指针,注意,但元素是空位的时候回调函数不会执行,最后返回的那个数组也还是空位,
forEach(function(e,i,arr),arr)类似map,但是不会返回数值,注意他不会中断执行,会把所有元素遍历完,一样会跳过空位
filter(function(e,i,arr),arr)
some(function(e,i,arr),this)只有一个返回true就true,
every(...)每个都符合
reduce(function(x,y,当前位置(0),原数组))从左到右累计处理,x代表累计变量,默认为第一个元素,y当前变量,默认第二个元素,
reduceRight()从右到左
indexOf(s, 开始搜索位置)返回参数在数值中出现的第一个位置,没有返回-1
lastIndexOf,出现的最后一个位置
注意 NaN不适用,因为这个方法是用===,NaN不等于本身
包装对象 Number(),String(),Boolean(), valueOf()分别返回123,“abc”, true, toString()分别返回“123”,“abc”,“true”
原型数据可以自动被转化为临时包装对象,使用后立即销毁,只读不可修改
用包装方法,不用 new 可以直接返回对应的值(不是对象了),相当于 new 包装对象().valueOf()
Number(实例方法)
toString()
toFixed(小数位数0-20位)返回一个指定小数位数的字符串
toExponetial(科学计数法小数位数0-20位)返回指定小数位数的科学计数法
toPrecision(有效数位)返回有效数位的字符串
String() 字符包装对象,实际是类数组对象,有length属性
静态方法 String.fromCharCode(多个unicode码的参数,不支持大于0xFFFF的字符)
实例方法
charAt(位置)返回指定位置的字符,如果为负数,或者超出范围就返回空字符
charCodeAt()返回指定位置字符的unicode值,
contact(位置)链接两个字符,返回一个新的字符串,不改变原字符,和Array对象的contact一样
slice(),类似array的方法
substring()和slice差不多,但是区别在于,如果参数是负数会变成0,而不是变成倒数,而且如果第一个参数大于第二个参数,则会自动调换位置
substr(开始位置(如果是负数变成倒数),未传则表示第一个(如果是负数变成0))
indexOf(s,开始匹配位置(往后匹配))字符在对象里面的第一个位置,如果没有返回-1,lastIndexOf(s,开始匹配位置(往前匹配))最后一个位置
trim(),去掉空格,\t,\v,\n,\r,返回一个新的字符串,不改变原字符
toLowerCase()小写,toUpperCase()大写,都不改变原字符
a.localCompare(b)返回整数,<0,=0,>0,是按我们自己的语言顺序,比如‘B’> 'a' false, 但是用该函数就是true
match(s)返回数组,成员是匹配的第一个字符串,没有返回null,返回的数组具有index和input属性,分别代表匹配开始的位置和原始字符串
search()类似,但是返回的是index
repalce()
split(s,返回的最大成员数)用s分割字符串,返回的是数组,
Math是js的内置对象,不能作为构造函数,只能用静态方法
Date表示时间范围是距离1970年1月1日 00:00:00前后各1一亿天,
new Date()参数有多种形式
1.毫秒数,表示距离那一个的毫秒数,若干参数用Unix时间戳作为参数,必须乘1000,因为他是以秒的
2.字符串,格式为“月 日,年 时:分:秒” 如果省略时间,会默认为0,其实其他时间格式也可以,只要可以被Date.parse()方法解析,注意es5里如果YYYY-MM-DD会变成iso时间格式,时间默认是08:00:00,其他的就是00:00:00
3.多个参数,(年,月[日,时,分,秒,毫秒]),必须两个
注意
月: 0-11,时:0-23,分:0-59,秒:0-59,毫秒:0-999,除了日:1-31
时间的运算,如果是加法,就是字符串相加,如果是减法就是间隔毫秒数
Date静态方法
Date.now(),返回距离那个时间的毫秒数 window.performance.now(),提供页面加载到命令运行时的已经过去的时间,可以精确到千分之一,
Date.parse(),解析日期字符串,返回毫秒数,解析失败返回NaN
Date.UTC(),返回UTC(世界标准时间)时间(date默认读取本地时间)
Date实例方法
toString(),跟直接读取对象实例一样,
toUTCString()
toISOString(),对应的iso8601写法(以utc时间为准)和toJSON一样
toDateString()返回日期字符串, toTimeString()返回时间字符串,toLocalDateString()当地时间日期格式,toLocalTimeString()
getTime,获取距离那个时间的毫秒搜,跟valueOf一样
getDate,返回几号,
getDay,星期几,星期日:0,星期一:1
getYear,距离那个时间的年数,
getFullYear, 返回年份
getMonth,返回月份
getHours,小时
getMillisecondes,毫秒
getMinutes,分
getSeconds秒
getTimezoneOffset距离世界标准时间的差异,以分为单位
有一些对应的 UTC方法,例如getUTCDate(),以此类推
set。。。参照get,
也有对应的 UTC方法,例如setUTCDate()
valueOf(),类似
Regex
两种方式
1. /xyz/g 2 new Regex(字符串, 'g')
属性
ignoreCase 是否设置了i修饰符,只读,表示是否忽略大小写
global,是否设置g,
multiline,是否设置m
lastIndex 下一次开始搜索的位置,可读写,一般只有设置了g才有意义
source,对象的字符串形式,只读
test(s),返回是否匹配s,只要匹配就停止了,除非,在调用一次,这是设置lastindex才有用,即使设了全局g,也是要调用多次才可以继续搜索
exec(),返回一个数组(失败null)第一个是整个匹配的字符串,如果有组,第二个对应,第一个括号的匹配,第三个参数对应第二个括号,,只要匹配成功就返回,不会再进行之后的匹配(和match不一样,match是返回所有匹配的字符串)。返回的数组包括input原字符串,index整个模式成功匹配的开始位置,可多次使用 ,如果正则是空字符串,匹配成功,但返回空字符数组
字符串对象的方法,
match匹配的所有结果(失败null),lastindex对他没用,因为他是全部匹配
search返回第一个匹配的位置,否则返回-1,会忽略g,lastIndex也无效
replace(),第二个参数可以设置$&匹配的字符,$`匹配字符前面的字符,'后面,n第n个组的内容(从1开始算),$$美元符号,也可以是一个函数,function(匹配的字符串,第一个组的匹配,第二个组的匹配。。。。匹配位置,原字符串)
'abc'.replace('b', '[$`-$&-$\']')// "a[a-b-c]c"
如果参数包括(),则组匹配也会返回,紧跟在对应匹配的位置
'aaa*a*'.split(/(a*)/) // [ '', 'aaa', '*', 'a', '*' ]
正则表达式的字符包括字面量字符和元字符,
元字符:
1 点字符(.)代表除了\r,\n,行分割(\u2028)和段分割符(\u2029)以为的所有字符
2 位置字符, ^开始$结束
3.选择字符 | 或者的意思,包括之前和之后的所有字符, ab|cd,包括ab, 或者cd,而不会b或者c
4.转义字符,需要的字符有 ^,$,[ , . ,( , ), |, * ,+ ? { , \\, 注意如果是用new RegExp得用两次,比如一般是\+,来匹配加法,如果用regexp得用\\+来匹配,
字符类 []
[abc]表示匹配abc当中一个就可以了
[^abc]脱字符,必须放在方括号的第一个位置,否则就不是这个用处了,匹配不能包括abc中的任何一个,用法: [^]可以匹配一切字符,包括换行符,
[a-z]a-z的范围中任何一个, [a-zA-Z0-9],-必须放在两个字符中间才有意义,不然就只代表字面意义
一些预定义的模式
\d [0-9],
\D [^0-9]
\w [A-Za-z0-9_]
\W[^A-Za-z0-9_]
\s 空格(包括制表符,空格符,断行符)[\t\r\n\v\f]
\S[^\t\r\n\v\f]
\b 词边界,也就是词与词之间间隔的符号,比如“abc abc”就是空格,
\B词于词没有边界
/\bworld/.test('hello-world') // true/\bworld/.test('helloworld') //false
/\Bworld/.test('hello-world') // false/\Bworld/.test('helloworld') // true
[\S\s]可以用来匹配一切字符,包括换行符,跟[^]一样
重复类
{n,m(可省略)}重复n到m次 lo{2,5},o重复2到5次,跟|不一样,他是前面或后面整个字符
量词类
? {0,1}
* {0,}
+{1,}
正则表达式是贪婪匹配,比如 a+来匹配aaa,match返回的结果是aaa,而不是a。可以在+后面加个?,就变成非贪婪匹配了,还有非贪婪*?
修饰符 i忽略大小写, g全局匹配 m多行模式,默认不加,针对^ 和$的行为,匹配事不会把换行符当做换行符,而是当做字符匹配, /word$/.test("hello word\n") false 加上m 返回true,^和$会匹配行首和行尾,知道多行,/^b/m.test('a\nb') // true
组匹配
match会返回组内匹配字符,但是不要用g修饰符,不然match不会返回组内字符,
可以用 \n表示第n个括号的内容,n从1开始,/(.)b(.)\1b\2/.test("abcabc"),true,其中\1表示第一个括号匹配的内容,这里是a,\2表示c
非铺获组
( ?:x)x代表组匹配,不返回改组的匹配内容,但是还是会匹配,
先行断言
x(? =y)只有x在y前面才匹配,并且组内字符y不返回
先行否定断言
x(?!y)x不在y前面才匹配,y同样不返回
JSON对象
严格的 json对象是这样的:
1.复合型的值只能是一般的对象和数组,不能是函数,正则,日期对象
2.简单型字符只能是字符串,数值(必须是十进制,不能是NaN,Infinity,-Infinity,),null,布尔值,(undefined)
3.字符串和键名只能用双引号
4最后一个元素不能加逗号
静态方法
stringify(值(可以是对像也可以是数组或其他的不一定是对象))把一个对象转化成一个严格的json字符串,可以被parse()还原,字符串会变成""abc""有两个双引号,如果对象中有个属性是函数,undefined,xml对象,就会跳过,如果属性中是数组, 数组里面有哪些,就变成null
JSON.stringify({ f: function(){}, a: [ function(){}, undefined ] }); // "{"a": [null,null]}"
stringify(正则)// "{}"
这个方法会忽略不可遍历的对象
第二个参数
1.数组(规定要转化的属性名,只有第一个参数是对象才有效)
2函数 function(key,value),如果返回undefined或者没有返回值,则这个属性被忽略
第三个参数
数字:表示每个属性要添加的空格数,不超过 10
字符串 :要添加每个属性前面的字符
如果第一个参数是个对象,并且有 toJSON方法,则直接用这个函数的返回值作为参数
parse方法,stringify的反向,
第二个参数可以是个函数,于 stringify里面一样的作用
属性描述对象
{
value:,
writable:(决定了value是否可以改变,默认true) ,
enumerable: (是否可枚举,默认true)
configurable:(默认true,如果false,不可删除属性,不可改属性描述对象的属性(除了value之外)) ,
get: 默认undefined,
set: 默认undefined
}
静态方法:
getOwnPropertyDescriptor(对象,属性)返回一个属性描述对象
defineProperty(对象,属性,属性描述对象)
defineProperties(对象,{属性名1:对象描述对象,属性名2: 对象描述对象2,。。。。})
如果设置了 get或者set,就不能一起定义value,也不能把writable设定为true,用这个两个方法设定的属性描述对象,3个属性描述对象的属性默认都是false。注意用var 声明时(其实是设置了一个当前环境变量的一个属性),configurable默认为false,不能删除,其他都可以
enumrable 可遍历性,用Object.prototype.propertyIsEnumerable,判断是否可枚举
如果为 false
for in (对应in )不会遍历(不管继承或者不继承的属性)
Object.keys(),不会遍历(也不会遍历继承的属性),如果要遍历自身所有属性(不管enumrale,),用Object.getOwnPropertyNames()
JSON.stringify()不会遍历,也不会遍历继承属性
configurable 设置为false时,设置其他属性,除了value(取决于writable),都会报错,但是writable从false设置为write才会报错
writable 如果派生对象的属性设置为false,继承对象对该属性赋值会失效,但是可以通过defineProoeryty定义,
get 属性名() {}
set 属性名() {}
对象拷贝(对象考虑要确定新对象和源对象有一样的原型对象,并且有一样的属性),如果属性描述对象中有存取器,直接用赋值进行拷贝只会拷贝值
可以用这种方式:
var extend = function (to, from) { for (var property in from) { var
descriptor = Object.getOwnPropertyDescriptor(from, property); if
(descriptor && ( !descriptor.writable ||
!descriptor.configurable || !descriptor.enumerable ||
descriptor.get || descriptor.set)) { Object.defineProperty(to,
property, descriptor); } else { to[property] = from[property]; } }
}
控制对象状态, Object.preventExtensions()(可以删除属性,但是不能调加新的属性,isExtensibl,false时,表示设置了preventExtensions)
isSealed())
。。。。差一节
面向对象
js没有类的概念,没有像c++那样的类对象来体现面向对象,js不是基于类,而是基于构造函数和原型链,构造函数里面的this指的是生成的对象实例,用new命令调用构造函数生成实例,如果没加new,则this指针指向顶层对象window
new的步骤如下:先创建一个空对象,作为对象实例,然后把对象的原型指向构造函数的prototype属性,然后把构造函数的this指针指向对象,完成
构造函数如果有 return语句,并且后面跟着一个对象(不是数字,字符串或者其他的东西),则new生成的是这个对象,否则不管怎样都是返回this对象,
如果是 new命令调用,则构造函数的new.target指向当前的函数,否则指向undefined
this指针很难,一般通过new创建实例的时候,this指向对象实例,但是可以通过赋值,改变this的指向,如果是在全局运行,则this指向window
var A = {
name: '张三',
describe: function () {
return '姓名:'+ this.name;
}
};
var B = {
name: '李四'
};
B.describe = A.describe;
B.describe()//姓名: 李四
只有用 obj.foo()这种方法,this才指向obj,其他的用法都是指向顶层环境:window(浏览器)或者global(node全局),module.exports(node模块环境中),严格模式下,this指针指向顶层对象会报错
// 情况一
(obj.foo = obj.foo)() // window
// 情况二
(false || obj.foo)() // window
// 情况三
(1, obj.foo)() // window
绑定 this的实例方法:
1.function.prototype.call(obj,参数1,参数2,。。。。)
obj应该是个对象,如果是空,null,undefined,就会指向顶层,如果是个原始数据类型,则会自动转化Wie对应的包装对象,一个用就是在实例函数覆盖掉原型函数的时候,可以通过Object.prototype.function.call(obj,参数)一样调用原来原型对象的方法
2.。。。。。.apply(obj,[参数1,参数2,...])
一个重要的用法是将一个类数组对象转化成正真的数组
Array.prototype.slice.apply(类数组对象)
3.....bind(obj),bind可以绑定一个参数,
var add = function(x,y){}, var a = add.bind(一个对象,5),a(6),执行时add里面的x就绑定5,运行时只要再绑定一个参数y 6就可以了,
注意 bind每次都返回一个函数,所以比如事件监听不能这样写
element.addEventListener('click', o.m.bind(o));
这样的话事件监听就取消不来了,因为找不到
element.removeEventListener('click', o.m.bind(o));失效
正确的写法是
var listener = o.m.bind(o);
element.addEventListener('click', listener);
回调函数的写法
callIt(counter.inc.bind(counter));
prototyoe原型对象
一般要这样写:
var MyArray = function() {}
MyArray.prototype = new MyArray();
MyArray.prototype.constructor = MyArray;
var mine = new MyArray();
每个对象都有一原型对象, Object.prototype 指向null,null没有自己的原型对象,其实每个函数都有prototype属性,他指向构造函数对应的原型对象,原型对象其实就是一个对象,并且有一个constructor函数,通过Object.getPrototype(对象)可以获取对象的原型对象
a(a只能对象,如果是undefined,null,或者其他原型数值,都返回false) instanceof b(b是个构造函数) a是不是b的实例(一个对象可以使多个对象的原型),相当于b.prototype.isPrototypeOf(a),
object.create(null) instanceof object //false
Object.getPrototypeOf(a),获取对象a的原型对象
Object.setPrototypeOf(a,b)返回一个设置a的原型对象为b的新对象,a一般放一个空对象{},也会对a进行改变
Object..create(a,b(可省略,一个属性对象,对象的属性是新对象的属性,属性是一个属性描述对象)),创造一个继承a对象的新对象,返回的新对象的原型就是a,a不可省略
创造一个空对象的方法:
var a = new Object();
var a = Object.create({})
var a = Object.create(Object.prototype);
a.isPrototypeOf(b)a是不是b的原型对象
a.__proto__可以用来改写一个对象的原型对象,这是一个浏览器才部署的内部属性,最好不用
有 3种方式获取原型对象,1, obj.__proto__ 2.obj.constructor.prototype3. Object.getPrototyeOf(obj)
只有第三种最可靠
继承
构造函数的继承
第一步:
子类的构造函数内,调用父类的构造函数
function super(){}
function super1(){}
function sub() {
super.call(this)(如果要多重继承,则可在写 super1.call(this),但是第一步只能指向一个,只能是一个的实例,即原型对象只能有一个,但是可以继承多个构造函数)
}
或者
function sub(){
this.base = super;
this.base()}
第二步:
sub.prototype = Object.create(super.prototype);
sub.prototype.constructor = sub;
单线程模式
js是单线程的,同一时间内只有一个线程在运行,但是可以是异步
Event Loop消息队列,一轮一轮地执行消息队列的线程,即回调函数
定时器,
正常任务 (settimeOut,setInterval,setmmediate,I/O,各种事件(比如鼠标单击事件))是在下一轮Event Loop执行,比如setimeOut(function(){},0)实际并不是立即执行,微任务(主要是promisehe process.nextTick),在这一轮任务都结束之后执行,比如Promise,所以执行任务,后执行Promis,在执行setTImeout
js异步执行的方式:
1,回调函数
2,事件监听,
3,发布/订阅,(观察者模式),先订阅,那个事件发生了就执行,之后某个动作触发了这个事件,
Promise是一个对象,目前Es6已经支持,是按同步的思路实现异步
var promise = new Promise(function(resolve, reject){
if() resolve(value);
else reject(value)
})
调用:
promise.then(f1(value),f2(value))f1代表成功时的回调,f2代表失败
promise.then(f1,f2).then(f3,f4),成功之后执行f1,并且f1也成功,才执行f3,如果f1失败执行f4
promise.then(f1).then(f2).then(f3,f4),执行失败或者f1,f2,当中任意一个失败,都执行f4
promise.then(f1).catch(f2),执行失败,或者f1失败,都会执行f2
DOM模型(document Object Model)文档对象模型,一个的对象,dom的标准: DOM3
节点( Node):对象,是最小单位
节点有几种类型(也可以说是 3种,元素节点,文本节点,属性节点)
1. document 整个dom树的顶层节点,代表整个文档,文档最高一层是html节点(树的根节点),nodeName: #document, 9,注意Document是个构造函数,document是个对象有nodeName属性
2.DocumentType: doctype标签(比如)nodeName: 等于DocumentType.name, 10
3.Element: 元素节点,就是一些标签 ,nodeName大写字母,比如HTML,1
4.Text 文本节点 #text 3
5.Attribute属性节点 属性名,比如id 2
6.Comment注释 #comment 8
7.DoucmentFragment,存在于文档中,但是还没被插入到dom树里,处于游离状态, #document-fragment, 11
节点的属性:
nodeName如上
nodeType如上
nodeValue(只有属性节点,comment节点,xml文档的cdata节点(不知道是什么)有,其他一律返回null)
textContent 返回当前节点和后代节点的文本内容,会把文本(不高考comment节点的)提取出来放在一起(只会提取文本),可读写,读的时候回忽略标签,写的时候会把字符串的标签进行转义,变成文本。text节点和Comment节点的值等于nodeValue,document节点和doctype节点返回null,如果要读整个文档的,用
document.documentElement.textContent
baseURI 任何节点一般都一样的,都是当前网页的url地址(绝对地址)有window.location决定,可通过标签进行改变,
节点的属性: ownerDocument,顶层文档对象,就是document对象,docuement对象的这个属性返回null
nextSibling 返回后面第一个同级节点,包括文本节点和评论节点
previousSibling 前面
parentNode父节点(只能是元素节点,document节点,documentfragment节点)
parentElement父元素节点,
childNodes子节点(不包含子孙节点哦),是一个nodeLIst集合,这时时动态的 firstChild,lastChild第一个和最后一个子节点
节点对象的方法
a(节点),把一个节点插入到子元素的最后一个位置,如果是一个已存在dom的节点,就转移到新的位置,不是克隆
hasChildNodes(),是否有子节点,
cloneNode(布尔值(true,克隆子孙节点,false,默认不克隆子孙节点))返回一个新的节点,属性都一样,但是事件没有克隆
a.inserBefore(b节点,a的子节点c)(有问题),把b插入到a的子节点c的前面,返回新的b节点,如果c为null,则插入到最后
如果要插入到后面,可用 parent.insertBefore(s1,s2.nextSibling);
removeChild(子节点)移除子节点
replaceChild(new, old),返回old节点
b.cotains(a)b是否包含a, 注意a.cotians(a)返回true
a.compareDocumentPosition(b)返回a和b的位置关系(还不是很理解)
isEqualNode(),返回是否相等,类型相等,属性相等,子节点相同
normalize(),去除空的文本节点,把比邻的文本节点合并成一个,
节点集合对象
NodeList对象,是个类数组对象,NodeList是构造函数,可能是静态页可能是动态的,
querySelectorAll,静态
ChildNode动态
遍历的最好方法是 for循环,和for( of)不要用for..in,会把length和item返回也遍历了,而且 不保证顺手
NodeList.item(index)=NodeList[index]
HTMLCollection对象,类数组,都是动态的,只能是节点元素,可以通过id和name获取,比如forms.id=forms.name=forms.item(index)=forms[index]
document.links,document.forms,document.images,
ParentNode接口
a.children 返回一个htmlcollection集合,包括所有子元素节点(不包括子孙),和childNode不同,后者又包含其他类型的节点
firstELmentChilid,lastElementChild,注意document节点的都是html节点
childELementCount子元素节点数量
ChildNode接口
remove()删除自己
before(),在自己前面插入一个同级节点,可插入文本节点,(有问题)
after(),(有问题)
replaceWith,(有问题)
document节点
window.document = document = 节点.ownerDocument
对于 iframe iframe.contentDocument
ajax返回的文档,用 XMLHttpRequest对象的 responseXML
内部属性:
1.doctype 对象,等于document.fistChild包含文档类型信息,对于html5,就是
document.doctype ""
document.doctype.name "html"
2.documentElement 文档的根节点,对于html文档就是html节点
3.defaultView,在浏览器中等于document对象所在的window对象,
4.body,head
5.activeElement文档中获得焦点的元素
.集合属性
document.links 所有设置href的a元素和area元素
.forms
.images
.embeds所有embed元素
.scrips 所有script元素,也是htmlcollection集合
.styleSheets 所有style元素,类数组对象,每个元素都有一个一个cssRules对象,代表这个样式表的样式信息
信息属性
documentURI 网址, URL也是,但是后者只有htlm文档具有,他们都是静态的,文档大锚点变化,他们不会变,但是location会变
domain域名 二级域名下,可以吧该值设置为一级域名
lastModified最后修改的时间戳,字符串,用Date.parse()转化成时间戳格式才能比较
location 对象,底下有属性
document.location.href // "http://user:passwd@www.example.com:4097/path/a.html?x=111#part1" document.location.protocol // "http:" document.location.host // "www.example.com:4097" document.location.hostname // "www.example.com" document.location.port // "4097" document.location.pathname // "/path/a.html" document.location.search // "?x=111" document.location.hash // "#part1" document.location.user // "user" document.location.password // "passed
方法:
// 跳转到另一个网址 document.location.assign('http://www.google.com') // 优先从服务器重新加载 document.location.reload(true) // 优先从本地缓存重新加载(默认值) document.location.reload(false) // 跳转到新网址,并将取代掉history对象中的当前记录,再点击后退,不会回到当前页面 document.location.replace('http://www.google.com'); // 将location对象转为字符串,等价于document.location.href document.location.toString()
location=新地址(可以是相对地址)相等于对location.href,调到一个新的网址
location='#top'锚地,跳到锚点
其他属性
document.referr,访问来源,如果是直接输入,返回空字符,于http头信息referer保持一致,
.title标题
.characterSet字符集,比如UTF-8, ISO-8859-1
.readyState,当前文档状态,loading加载html代码,尚未解析完,interactive加载外部资源中,complete加载完成
浏览器渲染过程:解析 html文档,loading,遇到script元素,并且没有async和defer属性,暂停解析,开始执行脚本,loading,解析完成interactive,等待加载外部文件,完成complete
.designMode是否可编辑,打开赋值为'on'
.implementation(接口(字符串),版本号(字符串))判断是否部署了某些dom接口
.compatMode兼容模式,一般设置了明确的DOCTYPE,都返回CSSCompat(严格模式),还有一种是BackCompat(向后兼容模式)
.cookie cookie信息
读写方法:
document.open(),write(),不会把标签转义,打开一个新的文档,等于清理了当前的文档,然后用write写,close关闭,关闭后就不能在write了,如果解析完成(DOMContendLoaded事件之后),在用write,会先调用open,把页面所有都清掉,之后的每次write只会追加,除非又用了close,这些都是老古董的方法,最好不要用
查找节点的方法
document.querySelector,
querySelectorAll
参数都是按 css选择器,但不支持css伪元素(比如:first-line)和伪类的选择器(:link,:visited),这两个也是元素节点的方法
getElementsByTagName(),返回htmlcollection对象,大小写不敏感,也是元素节点的方法
getElementsByClassName(), 返回如上,正常模式,大小写敏感同时符合多个用'foo bar'同时符合foo和bar类,次序不重要,也是元素节点的方法
getELementsByName nodeList对象,
getElementById大小写敏感,比querySelector高效,只是document的方法,
elementFromPoin(x,y)返回位于页面指定位置的最上层的元素节点
生成节点的方法
document_createlement('div')大小写不敏感
creatTextNode('hellodowew')会转义<>,但是不会转义引号
createAttribute(name) 通过生成对象的value属性赋值
var node = document.getElementById_x_x_x_x_x_x_x_x_x_x_x("div1"); var a = document_createAttribute("my_attrib"); a.value = "newVal"; node.setAttributeNode(a);
等于
var node = document.getElementById_x_x_x_x_x_x_x_x_x_x_x("div1");
node.setAttributeNode('my_attrib', 'newVal');
createDocumentFragment()
事件相关方法
creatEvent(事件类型) Event, UIEvents、MouseEvents、MutationEvents、HTMLEvents都可以,用字符串
新建事件的流程:
var e = document_createEvent('Event');
e.initEvent('build', true, true);
document.addEventListener('build', function(e){}, false);
document.dispatchEvent(e)
其他方法
hasFocus()当前文档是否有元素获得焦点
...其他方法不太常用
Elment节点
属性:
.attributes类数组对象,所有属性节点,动态的
.id .tagName
.innerHTML 内容, 如果文本节点中包含&、小于号(<)和大于号(>),innerHTML属性会将它们转为实体形式&、<、>会转义,所以插入script不会执行
outerHTML包括自身的
className class名
classList 类数组对象,每个属性都是类名,有这些方法,add(类名1,类名2...),remove(),toggle(true为添加,false为删除),cotains(),item(index)第index类名 ,toString()相等于className
盒子模式
详见照片
一些总结
整张页面,
当没有水平滚动条是 (这里不能用body的clientHeight)
document.documentElement.clienHeight === windows.innerHeight(包括滚动条)
如果元素没有溢出 scrollHeight === clientHeight
如果元素滑到底部
e.srcollHeight-e.scrollTop === e.clientHeight
如果元素没有溢出, offsetHeight 比clientHeight多了边框
整张网页的高度和宽度,可以从document.documentElement(即元素)或 元素上读取。 // 网页总高度 document.documentElement.offsetHeight document.documentElement.scrollHeight document.body.offsetHeight document.body.scrollHeight // 网页总宽度 document.documentElement.offsetWidth document.documentElement.scrollWidth document.body.offsetWidth document.body.scrollWidth 由于和的宽度可能设得不一样,因此从上取值会更保险一点。 视口的高度和宽度(包括滚动条),有两种方法可以获得。 // 视口高度 windows.innerHeight // 包括滚动条 document.documentElement.clientHeight // 不包括滚动条 // 视口宽度 windows.innerWidth // 包括滚动条 document.documentElement.clientWidth // 不包括滚动条 某个网页元素距离视口左上角的坐标,使用Element.getBoundingClientRect方法读取。 // 网页元素左上角的视口横坐标 Element.getBoundingClientRect().left // 网页元素左上角的视口纵坐标 Element.getBoundingClientRect().top 某个网页元素距离网页左上角的坐标,使用视口坐标加上网页滚动距离。 // 网页元素左上角的网页横坐标 Element.getBoundingClientRect().left + document.documentElement.scrollLeft // 网页元素左上角的网页纵坐标 Element.getBoundingClientRect().top + document.documentElement.scrollTop 网页目前滚动的距离,可以从document.documentElement节点上得到。 // 网页滚动的水平距离 document.documentElement.scrollLeft // 网页滚动的垂直距离 document.documentElement.scrollTop 网页元素本身的高度和宽度(不含overflow溢出的部分),通过offsetHeight和offsetWidth属性(包括Padding和Border)或Element.getBoundingClientRect方法获取。 // 网页元素的高度 Element.offsetHeight // 网页元素的宽度 Element.offsetWidth
盒子模式到此结束
相关节点属性
.children , .childElementCount, firstELmentChild, lastElementChild,nextElementSibling,PreviousELementSibling
offsetParent 返回最靠近节点的position不为static的元素节点,如果所有上层节点都不符合,就返回body,
关于属性的: getAttribute(),setAttribute(),hasAttribute,removeAttribute()
查找节点的: querySelector,querySlectorAll,(前面两个都是全局搜索,然后在匹配css查找器)getElementsByTagName,getElementsByClassName(后两个都是在当前范围内搜索)
closest(css选择器)返回最接近当前元素,并且符合css选择器的父元素,包括自己,所以会先在自己上判断是不是符合,然后在往上,如果自己符合就返回自己
matches(css选择器)判断自己是不是符合css选择器,带兼容前缀,
matches || webkitMatchesSelector || mozMatchesSelector || msMatchesSelector
事件相关的: addEventListener,removeEventListener,dispatchEvent
其他方法: scrolllntoView(true顶部重合,false底部重合)把当前元素滚到可见区域
Element.getBoundingClientRect()返回一个对象,提供盒子模式信息,返回的是相对于视口的值,都是从边框外计算的,所以都包括border和padding,(可能有滚动条,未证实)所以不是绝对的值,会随着滚到条变化,绝对的值要加上window.scrollX或者document.documentELement.scrollLeft
getClientRects(),返回一个类数组对象,表示元素在页面所有形成的矩形(块元素只有一个,但是行内元素会有多个)
element.insertAdjacentHTML(position, text);解析HTML字符串,然后将生成的节点插入DOM树的指定位置
位置有四种:
beforebegin:在当前元素节点的前面。 afterbegin:在当前元素节点的里面,插在它的第一个子元素之前。 beforeend:在当前元素节点的里面,插在它的最后一个子元素之后。 afterend:在当前元素节点的后面。
例子:insertAdjacentHTML('afterend', '
two
');
remove(),移除当前节点
focus()聚焦
属性节点
e.attributes['id']== e.id(只有标准属性) ==e.getAttribute('id') ==e.attributes[index] ==e.attributes.id
js对象的属性是大小写敏感的,但是html是大小写不敏感的,所以用对象的方法获取属性一律小写,并用骆驼写法,一些保留字要注意
class=>className
for=>htmlFor
dataset返回data-属性名,属性名只能包括小写字母 数值 - . : _
不能写成 data-helloWorld 要写成data-hello-world,获取是dataset.helloWorld
文本节点
创建: document_createTextNode(文本字符串) 相当于 new Text(文本字符串)
属性:
data 等于nodeValue
wholeText返回与当前节点相毗邻的文本节点
length文本字符串的长度
nextElmentSibling
previousElementSibling
方法:
appendData()追加文本
deleteData(开始位置,长度)
insertData(插入位置,字符串)
replaceData(替换开始位置,长度,字符串)
subStringData(开始位置,长度)返回一个字符串,原来的不变
remove()删除自己
splitText(分割位置)如果参数是3,原来变成0,1,2,返回3,4...与element.normalize()相反
DocumentFragment游离的一个dom片段
创建:
createDocumentFragment() 等于 new DocumentFragment()
一旦被加入到 dom树中,他自身就变成空了,可以再次被利用,如果要保存可以用cloneNode(true)复制一个
属性:
children,fistElmentChild,lastElmentChild,childElementCount
事件监听:
document,element,window都有这个接口
添加
addEventListener(事件名(大写敏感),回调函数,布尔值(默认fasle,冒泡时触发,true捕获是触发)),可以多次执行为同一个事件添加多个回调函数,按顺序,
removeEvenListener(同以上) dispatchEvent(Event对象(不能为空)),返回一个布尔值,如果回调函数用为了event.preventDefault(),才返回false
使用方法:
para.addEventListener('click', hello, false); var event = new Event('click');
para.dispatchEvent(event);
自定义事件方法:
var event = new Event('build'); elem.addEventListener('build', function (e) { ... }, false); elem.dispatchEvent(event);
另外一种:
var myEvent = new CustomEvent("myevent", { detail: { foo: "bar" }, bubbles: true, cancelable: false }); el.addEventListener('myevent', function(event) {}); el.dispatchEvent(myEvent);
ie的方法:(不支持各个事件类型的构造函数,不能用new Event)
var event = document_createEvent('Event'); event.initEvent('build', true(是否冒泡), true(是否可取消),对象额外信息); document.addEventListener('build', doSomething, false); document.dispatchEvent(event);
监听函数就是回调函数方式为:
1.html形式 on- load click 后面是可以执行的代码,不是函数,所以是 函数名()的形式
2.ELment节点事件属性(只能在冒泡触发)
window.onload = 函数名,
3.addEventListener()
回调函数的 this
addEventListener方法 总是指向监听回调函数并且执行函数的那个节点
on- 如果是函数,不会指向触发节点,指向全局,所以一般吧代码直接写在里面
指向触发节点的方法:
// JavaScript代码 element.onclick = print element.addEventListener('click', print, false) element.onclick = function () {console.log(this.id);} // HTML代码
事件传播
捕获(一次) -目标(刚捕获一次,要冒泡又一次)-冒泡(一次)
window-document-html-body-...-目标-目标-...-body-html-document-window
事件代理
由父节点监听事件,统一处理子元素的事件,
停止冒泡: even.stopPropagation()只会停止当前回调函数的传播,不会禁止相同事件的其他函数的传播,如果都不想了可以event. stopImmediatePropagation
Event对象
new Event(事件名,{bubbles: 是否冒泡,默认false,cancelable: 是否可以取消,默认false})
属性:
bubbles 返回是否冒泡
eventPhase,事件传播情况,0没法说,1捕获阶段,2目标阶段,3.冒泡阶段
cancelable 是否可取消
defaultPrevented 是否调用preventDefault
currentTarget 事件所在的节点,执行监听函数的节点,tartget(ie8以下,是用srcElement)事件发生的节点,一般是最底层的元素,如果是事件代理,currentTarget就是父元素指向this对象,target就是子元素
type 事件名,返回字符串
detail事件对应得某些信息,比如dbclick,detail总是2
timeStamp毫秒时间搓,事件发生的时间
isTrusted是否为真实用户触发
方法:
preventDefault()传播的各个阶段不执行默认行为
stopPropagation() stopImmediatePropagation()
事件的类型
鼠标事件:
mousedown-mouseup-click-dbclick
mouseover在元素里面移动是一直触发
mouseenter只触发一次,进入元素的时候触发
mouseout出去触发,会冒泡
mouseleave出去是触发,不会冒泡
contextmenu点击右键
MouseEvent对象继承event对象和uievent对象
new MouseEvent(事件名(以上那几种),初始化对象)
属性:
是否按下
altKey
ctrKey
metaKey
shiftKey
按下哪个键:
button: -1没有按下,0主键,1辅助键,2次键
buttons 返回十进制数(可转化为3位的二进制,个位表示左键,十位表示右键,百位表示辅助键 111(7)同时都按下)
位置:
clientX,clientY相对浏览器 screenX,screenY相对屏幕
movementX,moveMentY相对前一个位置的相对位移
relatedTarget次要 相关节点
wheel事件,鼠标滚动事件,继承mouseEvent
new WheelEvent(同上)
属性:
deltaX水平滚到量
delatY 垂直。。。
delatZ z轴。。。
delatMod单位 0像素,1行,2页
键盘事件
new KeyboardEvent,继承mouseEvent
keydown - keypress(除了alt,Ctrl、shift,met) -keyup
用户不松口顺序
keydown
keypress
keydown
keypress
。。。
keyup
属性:
是否按下的部分同 mouseEvent
key:键名
charCode 键的Unicode值,只有keypriess有,其他两个没有
进度事件:
new ProgressEvent()
abort 进度被终止,不包括发生错误被终止
error 发生错误无法加载(最好反正html上以onerror的形式),不会冒泡
load 成功加载结束
loadstart 开始加载
loadend 进度停止,error/abort/load后面
progress 经常中
timeout超时触发
属性: lengthComputable,是否可以计算进度
total 进度总长度
loaded 已完成长度
拖拉事件
。。。暂时不总结
触摸事件
Touch对象,触摸点
属性:
identifier 实例的唯一标识
screenX,Y,
clientX,y,
pageX,y(相对窗口的绝对位置,考虑到滚动条)
radiusX,y影响范围,椭圆的长轴和短轴
radiusAngle椭圆旋转角度,0-90度
force 压力,0没有压力,1有压力
target,触发节点
TouchList
比如三个手指触摸,就有三个 touch对象
TouchEvent对象,是个事件对象
是否按下:
同上
changedTouches返回一个touchlist对象,当前触摸事件引发的所有Touch对象
情况如下:
touchstart被激活的触摸点,
touchmove发生变化的触摸点
touchend消失的触摸点
targetTouches 返回一个touchlist对象,包含目标节点里面所有处于激活的触摸点
touches 返回touchlist对象,包含所有处于活动状态的触摸点
触摸事件:
touchstart
touchend target对象和touchstart的一样
touchmove 。。。。。一样
touchcancel触摸点取消
表单事件
input事件,input,textarea值发生变化时触发,会连续触发,没按下一个键就触发
select事件,input,textarea选中文本时
change input,textarea值发生变化并且丧失焦点时,,select完成选择,激活radio,checkbox,不会连续触发
reset
submit 发生的对象是form不是某个button
文档对象 window、body、frameset对象
beforeunload 窗口将要关闭,如下可弹出对话框,在关闭之前
window.addEventListener('beforeunload', function (e) { var confirmationMessage = '确认关闭窗口?'; e.returnValue = confirmationMessage;(非空的值就可以) return confirmationMessage; });
unload 发生在beforeunload和pagehide后面,如果用户是按下前进后退是不会触发的,所有资源依然存在,但是对用户不可以见,如果在window上定义了这个事件,则不会缓存页面
load成功加载(除了从缓存中加载),
error
pageshow 加载成功时触发,包括第一次和缓存加载,排在load后面,属性event.persisted,true表示缓存加载,
pagehide persited设为true则保存在缓存中,发生在unload之前
load-》pageshow-》pagehide-》unload
DOMContentLoaded事件(ie8不支持)
文档解析完毕,外部资源还没下载结束,比 load早很多在document对象触发
readystatechange发生在document和xmlhttpReques对象上,当readyState发生变化时触发
scroll事件,window上,会连续触发, 用requestAnimationFrame和settimeout可以限制触发事件的频率(不是很理解。。。)
resize事件,发生在window,body,framset
haschange事件,window对象,在url hash值变化时,
popstate事件 history对象发生显示切换的回收,只有点击前进后退,或者history.back(),history.forward,go()时才触发,
焦点事件 document对象和element对象
focus不会冒泡
blur失去焦点,不会冒泡
focusin 将要获得节点,会冒泡,fierfox不支持
focusout 将要死去焦点,同上
属性:
target 和relatedTarget,(foucs和blur为null)
css操作:
元素节点有个style对象,表示元素的行内样式,不包括 外链样式和内嵌
设置样式的方法 (主要是设置行内样式)
1。el.setAttribute('style','')
2. 通过style对象
类似 style.backgroundColor='#000'的方法,注意这种方法要用骆驼表示法,并且要写单位,并且不能用margin这种简写,style对象有一个cssText属性返回样式的字符串,
通过
typeof el.style.样式名 === 'string'可以判断是否支持这个样式,如果行内样式没设置,也会返回一个空字符串,但是如果不支持,会返回undefined
判断函数:
function isPropertySupported(property){ if (property in document.body.style) return true; var prefixes = ['Moz', 'Webkit', 'O', 'ms', 'Khtml']; var prefProperty = property.charAt(0).toUpperCase() + property.substr(1); for(var i = 0; i < prefixes.length; i++){ if((prefixes[i] + prefProperty) in document.body.style) return true; } return false; } isPropertySupported('background-clip') // true
style对象的方法:
setProperty(name, value)
getPropertyValue(name)
removeProperty(name)
window.getComputedStyle(元素节点, 伪元素(可省略,':before',':after',‘:first-line’,‘:first-letter’))返回节点最终的样式,包括外链样式和内嵌的效果,返回的单位有带px,颜色是rgba格式,不能用简写,只能读不能写
有一个方法 getPropertyValue(name),同style对象的方法
伪元素:
不能用style对象读取,只能用 window.getComputedStyle读取
StyleSheet对象代表一张样式表,包括外链和内嵌
1.document.styleSheets类数组对象,返回页面的所有样式表
2.通过link和style节点的sheet属性可获取他们对应的stylesheet对象
link节点.sheet
stylesheet的属性
1.media media.mediaText ‘screen’用于屏幕,‘print’打印,‘all’两者都适用
2.disable可读写,赋值为true或者‘disabled’代表关闭一张样式表
3.href 内嵌返回null
4.title
5.type 一般为text/css
6.parentStyleSheet 返回样式表中通过@import外部导入的样式表,没有返回null
7.ownerNode,所在dom节点,一般是link或者style节点,如果是被其他样式引入的,则返回null
8.cssRules,类数组对象,代表每条css规则
document.querySelector(link节点).sheet.cssRules[0].cssText // "p { line-height: 1.4em; color: blue; }"
document.querySelector(link节点).sheet .cssRules[0].style.color = 'red';