方便起见不分parameter[形参,出现在函数定义中]和argument[实参,其值为传入函数的值],一律当作argument记录
javascript会在上下行无法合并解释时自动添加行末封号,++和--加在前面,{}当与语句同行
1 改变元素内容:点击显示日期时间
<button onclick="document.getElementById('ID').innerHTML="/'html语句"/'">
内容
</button>
<p id="ID"></p>
- 访问元素:
document.getElementById('ID')
2 改变属性
<button onclick="document.getElementById('ID').属性='值'">内容</button>
<button onclick="document.getElementById('ID').属性.子属性='值'">内容</button>
- 隐藏/显示元素
<button onclick="document.getElementById('ID').style.display='none/block'">
3 外置脚本
<button onclick=函数名(参数)>内容</button>
<script>
function 函数名(参数){
pass
}
</script>
或
<script src="文件"></script>
- 放在head? body? 一般都放body吗?
- 放body底部会加快加载速度
4 输出方式
- 使用
[window.]alert()写入警告框 - 使用
document.write()写入 HTML 输出- 会覆盖加载完的HTML文档,仅用于测试
- 使用
innerHTML写入HTML 元素 - 使用
console.log()写入浏览器控制台
5 变量[也可以初始化]
声明
-
var 变量名;- 弱类型,声明关键字无区别,可动态变化
- 字母/_/$开头[数字: 字符串]
- 命名: 小写打头的驼峰式
- 自动提升[Hoisting]声明,但不提升初始化
- 可以重新声明
-
let- 声明只在本作用于中可见的变量;
- 在
HTML中用let声明全局变量,不自动变成window的属性 - 同一作用域中不能重新声明,不能重新声明
var也不能被var重新声明 - 没有自动提升
-
const常量- 可见方式和重复声明与
let相同 - 必须初始化
- 声明成初始值→不可改;声明成对象→属性可改
- 可见方式和重复声明与
类型
原始数据类型PrimitiveValue
- 数字/number
- 没有int/long/float/...的区别,实际存储的是字符串
- 八/十六进制:
0/0x开头 - [?]浮点数在计算前储存的是字符串
- 科学计数法: 数字[正负号]e指数
- 字符串/string ""/''
var 变量=""- 串内换行用\ [同python]
- 属性与方法见
String对象
-
undfined类型和值都是undefined,是变量未被初始化时的类型,也是调用没有返回值的函数时出现的类型- 可用于清空值/取消引用
-
boolean-
truely/falsely变量:!!a===true/false
-
Symbol
复杂数据类型
-
对象[类]/object {key: value}[python: 字典]
var 对象={ index1:{key11:value11, key12:value12, ...}, index2:{key21:value21, key22:value22, ...}, ... };被命名值的容器
-
访问对象属性
property in 实例对象:in检查对象是否拥有属性,不分辨为继承与否-
for ([var] peoperty in 实例对象)-
顺着原型链找出实例对象的所有属性
function inheriedPropertiyNames(obj){ var props={}; while(obj){ Object.getOwnPropertyNames(obj).forEach(function(p){ props[p]=true; //将obj每个属性的同名属性放入props }); obj=Object.getPrototypeOf(obj); } return Object.getOwnPropertyNames(props); }
-
全局对象
window创建实例[对象]
var 变量(实例对象)=[引用]new Object[(value1, ...)]与obj={}等价销毁/废除实例[对象]
变量(对象)=null作用域:只有公有,但习惯用
对象._属性/方法_来表示私有;使用静态作用域-
对象的自带属性
-
constructor引用构造函数的指针 -
prototype引用对象原型的指针,原型链最终指向null;如果要改变,需要同时修改constructor.prototype -
name构造函数名称 -
__proto__对象的原型,尽量少用,用Object.getPrototypeOf(obj)
-
-
对象的自带方法
-
实例方法
hasOwnProperty(property)判断是否为继承来的属性isPrototypeOf(object)调用此方法的对象是否是object的原型propertyIsEnumerable()-
toString/LocalString()👉
Object.prototype.toString.call(实例)=[object 类型]否则实例所属的对象的toString()可能覆盖它var type=function (o){ var s=Object.prototype.toString.call(o); //组匹配的第一个匹配的组的小写 return a.match(/\[object (.*?)\]/)[1].toLowerCase(); };//返回对象类型 //遍历数组,对其中的每个值创造一个函数,作为对象type的属性"is+这个值"的值 ['Null','Undefined','Object','Array','String','Number','Boolean','Function','RegExp'].forEach(function (t){ type['is'+t]=function (o){ return type(o)===t.toLowerCase(); }; }); type.isRegExp(/abc/); //true valueOf()返回数值/原始值/对象本身[object 类型]
-
静态方法
-
属性
-
属性描述对象
attributeObject的属性/元属性:value:undefined只要writable/configurable有一个true就能改writable:truefalse时修改不会报错[严格模式会],但改不了enumerable:truefalse:不可枚举/秘密,不可以for...in/Object.keys()/JSON.stringfy()读取configurable:truefalse:不可删除,不可配置,value/writable/enumerable/configurable皆不可修改get:undefined[writable必为false,不可同时定义value]-
set:undefinedvar obj={ a:value, //b属性依赖内部属性a get b(){ return this.a; }, set b(value){ if (条件) this.a=value; else throw new Error('message'); } }; obj.b; obj.b=value;
Object.getOwnPropertyDescriptor(实例,'属性')获取属性描述对象,不能用于继承的属性[如:方法]Object.prototype/实例.propertyIsEnumerable('属性')Object.keys(对象)[常用]/Object.getOwnPropertyNames(对象)返回"属性名"数组,前者只返回可枚举属性-
Object.defineProperty(object对象, propertyName属性名, atrributesObject属性描述对象)/Object.defineProperties (object, {propertyName:attributeObject}):writable/confuguable/enumerable默认值为falsevar obj=Object.defineProperties({},{ //新建一个空对象 p1:{value:1, enumerable:true, ...}, p2:{value:2, enumerable:true, ...}, p3:{get:function (){return this.p1+this.p2}}, ...} }); -
对象的[深]拷贝
//方法1 var extend=function (to,from){ for (var property in from){ //读取对象的属性 if(!from.hasOwnProperty(property)) continue; Object.defineProperty( to, property, Object.getOwnPropertyDiscription(from,property); ); } return to; } extent({},{get a(){return 1}}); //调用 //方法2 function copyObject(orig){ return Object.create( Object.getPrototypeOf(orig), Object.getOwnPropertyDescriptors(orig) ); }
-
-
状态
-
Object.preventExtensions(实例)使实例/对象无法添加新属性,如果尝试,严格模式下会报错👉
Object.isExtensible(实例)检查实例/对象是否可以添加新属性 -
Object.seal(实例)不能增不能删,实为Object.getOwnPropertyDescriptor(对象, 属性).configurable=false👉
Object.isSealed(实例) -
Object.freeze(实例)不能增不能删不能改,将实例/对象变为常量,如果尝试,严格模式下会报错👉
Object.isFrozen(实例)→if(!Object.isFrozen(实例)) ; 绕过三者:使用
var proto=Object.getPrototypeOf(实例);proto.属性=value;更改上述三种冻结只能冻属性指向某对象,不能冻结属性指向的值,如
被冻结的实例.属性[值为一个数组].push('内容')可以发生
-
-
原型链
Object.getPrototypeOf(obj)-
Object.setPrototypeOf(被设置对象, 原型对象)可以返回被设置对象var f=new F(); //等同于 var f=Object.setPrototypeOf({},F.prototype); F.call(f); -
Object.create(obj)返回以obj为模板的新对象,后者继承obj所有属性;obj不能是原始类型对象var obj=Object.create(null)一个没有valueOf()、toString()的对象对
obj1的修改会影响到obj2-
等效
Object.create=function (obj){ function F(){} F.prototype=obj; return new F(); } 可以有第二个参数,给新对象新增属性,写法同
Object.definePropertiesOf()的参数
-
-
-
引用类型[≈子类?]
-
数组/array [value 1, value 2, ...]
数组名[下标]length-
遍历
forEach(函数)function 函数(value项目值, index项目索引, array数组[可不全])会跳过空位但不跳undefined-
map(函数[参数同上])对每个元素执行函数并创建新数组 -
filter(筛选函数)对每个元素执行筛选函数并创建新数组 -
reduce/reduceRight(函数[, 初始值])function 函数(total初始值/上一个返回值, value, index, array[可不全])对每个元素迭代函数并创建新数组 -
every(筛选函数)所有通过返回true -
some(筛选函数)存在通过的返回true
-
检索
indexOf(item[, start])/lastIindexOf(item[, start])/find(func(value, index,array))/findIindex(func(同前))添加
push(元素)返回新数组长度/unshift()在首位添加元素并移位,返回新数组长度删除
pop()返回被删元素/shift()删除首个元素并一并移位,返回被删元素/delete 数组[下标]但会留下空洞empty改
数组[下标]=元素替换
splice(替换位置, 删除元素个数, 加入元素1, ...)删除可>加入,不留空洞合并
concat(被合并数组1, ...)切片
slice(起始下标[, 终止下标/default=length-1])判断类型
Array.isArray(数组)/变量.constructor.toString(). indexOf("Array")/instanceof合并为字符串
toString()以,分隔/join([分隔符])-
排序
sort()按顺序根据字符编号排对数值排:加入比值函数
数组.sort(function(a, b){return a-b})根据返回值正负摆放前后位置找最值:用
sort()取数组[0]和数组[length-1]/调用Math.max.apply(null, 数组)/自定义在对象中排序:
return a.key-b.key
反转顺序
reverse()Array对象
null类型和值[字面量]都是null,“对象的占位符”Boolean对象-
Math对象没有构造函数,属性时常量,方法是函数,不必为此创建一个对象后调用
PI/E/SQRT2/SQRT1_2/LN2/LN10/LOG2E/LOG10Eround/ceil/floor(x)四舍五入/向上/向下取整pow(x, y)x的y次方log(x)ln(x)sqrt(x)abs(x)exp()科学记数法sin/cos/tan(rad)asin/acos/atan(x)[rad]/atan2(x,y)[°]max/min(x1, x2, ...)-
random()[0,1)间随机数function getRandOnt(min, max){ return Math.floor(Math.random()*(max-min))+min }
-
Number对象-
MAX_VALUE/MIN_VALUE仅以Number.调用 -
POSITIVE_INFINITY/NEGATIVE_INFINITY仅以Number.调用 -
toFixed(位数)指定小数位数 -
toExponentional(指数)转换为科学计数法 -
toPercision(精度)根据精度显示数
-
-
String对象lengthcharAt(下标)返回字符(的字符串)charCodeAt(下标)返回字符的编码concat(string)返回接好的字符串, 作用同+indexOf(string[, 起始下标])/lastIndexOf(string[, 起始下标])从头/尾[或开始下标]开始向后/向前检索子串, 搜到返回第一个匹配串的开始下标,搜不到返回-1;不可以用于正则式search(regex)功能同上,不可设置起始参数,可用于正则式match(regex)类似Regex.prototype.exec(str),但会一次性返回所有成功结果,Regex.prototype.lastIndex属性对此函数无效-
replace("被替换字符串/正则式", "替换字符串"/function (match){return ;})- /字符串/i:忽略大小写
- /字符串/g:匹配所有[详见正则式]
localeCompare()按顺序依次比,对象的字符在前[在字符集中值更小]/一样/后返回-1/0/+1slice/substring([取较小的值作]start, end)后者忽略负数,当0处理/substr(start[可取负], length)toLowerCase()/toLocaleLowerCase()toUpperCase()/toLocaleUpperCase()trim()删除字符串两端空白-
split("字符串中的分隔符(字符串/正则式)"[, 最大成员数])将字符串分割为数组👉
split("")会按字符分隔
-
Date对象创建
new Date()/new Date(year[两位数会解释为19xx], month, …, milliseconds[👈存储方式&单个参数默认])/new Date(dateString)显示 default:
toString()/toLocalString()短日期+时间/toUTCString()/toDateString()-
创建格式
格式名 格式 默认输出 星期[3] 月份[3] 日 年[4] 时分秒 时区 ISO日期 年[4]-月[2]-日T时:分:秒Z/+/-相对时区 短日期 月[2]/日/年[4] 或 年[4]/月[2]/日 长日期 月[3或全程] 日[或反过来] 年[4] 获取/设置时间
get/set[UTC]Date/FullYear/Month[始自0的月号]/Day[始自0的星期号]/Hours/Monutes/Seconds/Milliseseconds/ Time()
-
Regex对象var reg=/正则式/修饰符-
[实例]属性
ignoreCase-
global用于匹配所有匹配串 multiline-
flags按字母顺序返回所有修饰符 -
lastIndex带g修饰符时可指定开始搜索位置,可写,只对一个正则表达式有效 -
source正则表达式字符串形式
-
[实例]方法
test(str)匹配,能匹配返回true-
exec(str)匹配,发现匹配返回匹配成功的子字符串/结果,否则返回null如果有组匹配/正则式含圆括号,返回
[匹配结果,匹配成功组1, ...]属性:
index匹配成功开始位置/input:str
var reg=/正则式/g; var str='匹配串'; while(true){ var match=reg.match(str); if(!match) break; console.log('#'+match.index+':'+match[0]); }
-
匹配规则啊我丢失一半的python笔记啊
字面量字符
-
元字符
.除回车换行分隔符都能匹配^字符串开始$字符串结束|或,自动包含前后的所有字符\转义符[]字符类{}重复类?={0,1}*={0,}+={1,}()子组...
转义符 需要匹配与元字符相同的字符,前加
\;如果用new RegExp(), 加\\特殊字符
\n/\r/\t/\v/...-
字符类
[字符]匹配一个即可-
[^字符]脱字符,除字符之外匹配一个即可,[^]可匹配换行符,但必须在首位 -
[字符-字符]连字符,在[]间才有效,只读取左右单个字符,也可匹配Unicode
-
-
预定义模式/简写
-
\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]👉/\S\s/可指代一切字符 -
\b=词的边界\B=非词边界[-两边也算词的边界]
-
重复类
{n}/{n,}/{n,m}量词符
?/*/+贪婪模式[默认]/非贪婪模式[在量词符之后添加
?/[+/*/?]?某个模式出现量词符对应的次数时,采用非贪婪模式]修饰符
g全部匹配/i忽略大小写/m多行[^/$匹配行首行尾]-
组匹配
- 不同时与
g修饰符使用,str.match(reg)不捕获分组内容,可配合循环使用reg.exec(str)匹配所有 - 可使用
\n引用第n个组匹配 -
(?:内容)非捕获组:会进行分组匹配,但不会占用组匹配位置 - 先行(否定)断言
匹配(?=/!会/不会出现的东西)
- 不同时与
-
JSON对象- 值只能是数组/对象[键名放进"",最后一个成员后不能带逗号]/"字符串"/十进制数/
boolean/null - 静态方法
-
JSON.stringify(转换对象)转化为JSON字符串-
"str"会变成"\"str\"" - 不符合规范的属性被过滤/数组成员变为
null/正则对象变空对象 - 忽略不可遍历属性
- 可以有参数2,转为字符串的键[白名单]/处理方法返回值的函数[会处理每个键]
- 可以有参数3,每个属性前增加的空格数,用于排版
- 转换对象的
toJSON方法[如果有]会覆盖JSON.stringify()方法
-
-
JSON.parse('JSON字符串', 参数2[同上])转化为对应的值
-
- 值只能是数组/对象[键名放进"",最后一个成员后不能带逗号]/"字符串"/十进制数/
-
-
函数/function[
Function对象的实例]不是对象的方法就是全局对象
window的函数-
arguments对象[实参对象]- 参数组,有属性
length,最多25 - 即使定义时里没有参数,调用时也可以传参数进此组,可用于重载
- 用
if写默认参数,否则参数没传够会是undefined
- 参数组,有属性
Function对象-
创建实例
静态方法
function 函数名([args]){pass;}动态匿名方法/构造器
var 函数名=new Function("参数1", "参数2", ..., "函数语句")[可避免👇]-
直接量方法/表达式
[var ]函数名=function ([args]){pass;};👉自调用/匿名闭包
函数名=(function (){pass;})(); 箭头函数
const 函数名=(args) => {return pass};length函数期望[定义]的参数个数toString()/valueOf()会返回函数的文本[function...}]-
call()拥有方法的对象.方法.call(调用方法的对象[this], arg1, ...) -
apply()与call()类似,接受数组类型的参数拥有方法的对象.方法.call(调用方法的对象[this], [args])
闭包
类型转换
自动转换
运算符&
string&number:从左到右,对字符串使用valueOf()/对数字使用toString()valueOf()优先级高于toString()输出时自动对变量使用
toString()-
原始值→对应的复杂实例
- 原始类型调用了属于复杂类型的属性/方法:自动根据前者生成一个复杂类型对象实例“包装对象实例”并显示调用结果
- 可以使用
复杂实例=Object(原始值)实现转换
转换函数
变量.toString([基数])
aNull=null;
aNull.toString(); //会报错
-
parseInt(string[, 基数])左至右有一位不是数字即返回,认0/0x,不认./parseFloat(string)不认0/0x,不认第二个.,没有基数功能 - 强制类型转换
Boolean(value)true: 非0数字/非空字符串/非空对象;false: 0/空字符串/undefined/null-
Number(value)整个值可以转换为数字才不返回NaNNumber(null)==0Number(new Date(["日期"]))返回1970/1/1至日期的毫秒数-
Number(object)==NaN,除非是单值数组。操作:var obj={属性: 值}; Number(obj); //等同于: if (typeof obj.valueOf()==='object'){ Number(obj.toString()); //[object Object]→NaN } else{ Number(obj.valueOf()); }
String(value)什么都能原样转,null也转
类型判断
typeof 变量function isDate(变量){ return 变量.constructor===类型; //return 变量.constructor.toString.indexOf("类型")>-1; }
6 注释
- 单行//
- 多行/* */
7 运算符
| 运算符 | 意义 |
|---|---|
| === | 等值等型[无需等性运算前转换类型就相等] |
| !== | 不等值/不等型 |
| (condition)?: | 三元运算[条件是运算符] |
in |
是否为(读取?)某对象的属性 |
instanceof |
是否为某对象的实例,等同于对象.prototype.isPrototype0f(实例)
|
typeof |
返回类型,对没有声明过的变量会返回undefined
|
delete |
取消对象的引用,使之成为undefined
|
void |
返回undefined
|
| +/- | 可以将字符串转化为数字[并求负] |
yield |
暂停函数[python: 生成器] |
| , | 常用于变量声明[x,y=y,x应该不行] |
| >>/>>> | 有/无符号右移 |
| &/|/^/~ | 位运算与/或/异或/非[EMAScriptAND OR],自动变成32位 |
| &&/| | 逻辑运算与/或 |
| </>/== | 👉关系/等性运算中,一方为数字,另一方[字符串/boolean]自动转换为数字 |
8 特殊的值
| 类型 | 值 | 意义 |
|---|---|---|
undefined |
undefined |
只声明未定义的变量值 👉 null==undefined
|
object |
null |
被定义过的空值 |
| number | NaN |
not a number 判断函数: isNaN()👉 NaN与任何关系运算符的运算结果都是false,等号为flase不等号为true
|
| number | +/-Infinity
|
无穷,详见Number对象判断函数: isFinite()
|
9 逻辑值转换
| 输入 | 输出 |
|---|---|
undefined |
false |
null |
false |
boolean |
结果等于输入的参数(不转换) |
| number | 如果参数为 +0, -0 或 NaN,则结果为false;否则为true。 |
| string | 如果参数为空字符串,则结果为 false;否则为 true。 |
| object | true |
10 类/对象
-
new操作符- 创建一个新的实例对象,赋予此对象当前函数的作用域
- 将空对象的原型指向构造函数的
prototype属性,将空对象赋给函数内部的this关键字 - 执行构造函数[对象同名函数]
- 无显示返回对象,则返回此新对象
-
new.target:当前函数以new操作符建立则指向当前函数,否则为undefined
-
this关键字当前所在的对象[运行环境]
-
使用方式
- 全局:
this→顶层对象window - 构造函数
- 对象的方法:
this→当前一层对象/属性/方法
- 全局:
把对象的方法赋给全局变量会让
this指向window,需要将对象赋给全局变量再调用方法-
多层函数/数组的遍历函数/回调函数中的
this会指向全局/全局/DOM对象(本质是函数作为参数的时候会成为全局对象的方法?),需要使用变量[常用that]固定this的值并在内层调用//多层函数 var o={ f1:function(){ console.log(this); var that=this; var f2=function (){ console.log(that); }(); //函数自调用 } } o.f1(); //Object//Object //数组遍历 var o={ v:'hello', p:['a1','a2'], f:function f(){ //1 用that固定this var that=this; this.p.forEach(function (item){ console.log(that.v+' '+item); }); //2 用参数固定运行环境 this.p.forEach(function(item){ console.log(this.v+' '+item); },this); } } 0.f(); -
在函数中绑定
this:Function.prototype.call([this, default:window])方法-
apply([this], [args])方法- 用
Array.prototype.slice.apply({p:v,length:n})转换类似数组的对象[必须有length]
- 用
-
bind()每次返回一个新的函数,它得到了参数1的环境,但被绑定的方法/函数不用立即执行:
函数=拥有方法的对象[default:window].对象的方法[被绑定函数].bind(绑定到的对象[环境], 方法的参数)-
也可以用来固定被绑定函数的参数:
function add(x, y){ return x+y; } var puls5=add.bind(null,5); //null/undefined: this→window puls5(10); //15 多层函数/数组的遍历函数/回调函数中的
this会指向全局/全局/DOM对象,可以在传入函数时增加.bind(需要的环境)-
结合
call():var push=Function.prototype.call.bind(Array.prototype.push); //bind:让全局函数push拥有数组的方法 //call:让 var a=[1,2,3]; push(a,4);
构造/声明与实例化
-
工厂方式[实际上发生的事]
function 方法1(){ //为了让每个实例调用同一个方法[共享成员函数] pass; } function create(arg1, arg2, ...){ //为了创建多个实例、重复调用而设 var 变量[对象]=new Object(); 变量.attr1=arg1; 变量.attr2=arg2; ... 变量.方法1=方法1; ... return 变量 } var 实例1=create(value1, value2, ...) var 实例2=create(value1, value2, ...) -
构造函数方式
constructorfunction 对象(arg1, arg2, ...){ this.attr1=arg1; this.attr2=arg2; ... this.方法1=function(){ //不放在外面,依然用不了同一个函数 pass; }; ... } var 实例1=new 对象(value1, value2); var 实例2=new 对象(value1, value2); -
原型方式
prototypefunction 对象(){ //构造函数 } 对象.prototype.attr1=value1; 对象.prototype.attr2=value2; ... 对象.prototype.方法1=function(){ pass; }; ... var 实例1=new 对象() //可以使用instanceof检测对象类型 var 实例2=new 对象() //问题:不能传值且属性会被共享- 给本地对象[number/string/...]添加新方法
Object.prototype.方法=function (){ pass; }; - 重定义已有方法
Function.proptotype.original方法=Function.prototype.方法 Function.prototype.方法=funtion (){ pass; } - 极晚绑定[原本是晚绑定]:先定义实例再增加方法
var 实例=new Object() Object.prototype.方法=function (){ pass; };
- 给本地对象[number/string/...]添加新方法
构造函数/原型方式:属性用构造函数,方法用原型
-
动态原型方式
function 对象(arg1, arg2, ...){ this.attr1=arg1; this.sttr2=arg2; ... if (typeof 对象._initiallized=="undefined"){ //即:加个判断 对象.prototype.方法1=function(){ //直接量方法 pass; } 对象.prototype.方法2=function(){ pass; } ... 对象._initiallized=true; } }
继承
-
对象冒充
function SubClass(arg1, arg2, ...){ this.newMethod=SuperClass; //引用构造函数 this.newMethod(arg1); //调用构造函数 delete this.newMethod; //取消引用 this.attr2=arg2; ... this.aMethod=function (){ pass; }; } -
使用
call()/apply()方法的对象冒充function SubClass(arg1, arg2, ...){ SuperClass.call/apply(this, arg1/new Array(arg1)); //使用构造函数 this.attr2=arg2; ... this.aMethod=function (){ pass; }; }; -
原型链[不支持多重继承]
function SuperClass(){ } SuperClass.prototype.attr1=value1; SuperClass.prototype.method=function (){ pass; }; function SubClass(){ } //SubClass.prototype=new SuperClass(); //需要派生类继承基类所有方法时再用 SubClass.prototype=Object.create(SuperClass.prototype); //派生类继承基类原型 SubClass.prototype.constructor=SubClass; //指定构造函数 混合方式:属性用对象冒充,方法用原型链
-
多重继承
function M1(){ //Mixin混入 this.attr1=value1; } function M2(){ this.attr2=value2; } function SbuClass(){ M1.call(this); M2.call(this); //对象冒充方法 } SubClass.prototype=Object.create(M1.prototype); Object.assign(SubClass.prototype,M2.prototype); SubClass.prototype.constructor=SubClass; var s=new SubClass();
模块
定义:一组封装好的属性和方法,实现特定功能
写成对象:可能被改👇
-
封装私有对象
构造函数:同时存塑造和保存实例,违背构造函数设计目的,且耗内存×
-
立即执行函数:基本写法
var module=(function (){ var _count=0; var m1=function (){ //... }; var m2=function (){ //... }; return { m1:m1, m2:m2 }; })(); //自调用函数-
模块放大
var module1=(function (mod){ mod.m3=function (){ //... }; return mod; })(module1); //宽放大模式 })(window.module1||{}) -
输入库/全局变量-命名空间
var module=(function ($,window,document){ function initialize(){ //... } function dieCarouselDie(){ //... } //... window.finalCarousel={ init:initialize, destroy:dieCarouselDie //外部可调用的只有这两个属性 } })(jQuery,window,document)
-
11 事件
-
事件的传播
- 阶段
- 捕获:
window→目标节点 - 目标:事件触发[最深的触发节点默认为目标节点,
event.eventPhase覆盖为target] - 冒泡:目标节点→
window
- 捕获:
- 事件的代理
delegation:在父节点上添加监听函数,同时处理子节点的事件- 阻止传播但不取消监听函数:
event.stopProgagation() - 阻止两者:
event.stopImmediatePropagation()
- 阻止传播但不取消监听函数:
- 阶段
-
[过时了]HTML事件
<element envent="代码">→GlobalEventHandlers接口,由HTML元素/document对象/Window对象继承-
onchange/onfocus/onblur/onselect/onsubmit -
onclick/ondblclick/onmouseover/onmouuseout/onmousemove -
onkeypress/onkeydown/onkeyup -
onload/onunload/onreset/onerror[js错误:message/source/lineno /colno/error/资源加载错误]/onabort/onresize document.oncontextmenu=funtion (){return false;}<dialog>:oncancel/close
-
-
DOM事件操作接口:element.on事件=监听函数重复定义会覆盖👆 以上两者皆只在冒泡阶段被触发
-
EventTarget接口-
addEventListener('type', listener监听函数[, useCapture-t捕获[←默认]f冒泡])-
type事件类型 -
listener监听函数,有handleEvent方法的对象也可以 -
useCapture/{capture, once, passive} - 添加多个监听函数,按添加顺序执行;自动跳过重复的监听函数
- 可以使用匿名闭包往监听函数装参数:
function (event){listener(para);} -
event当前事件this当前事件所在的对象
-
-
removeEventListener('type', listener, false)必须在同一元素节点上移除用👆添加的同名监听函数,第三个参数也相同 -
dispatchEvent(event)在当前节点触发Event对象,返回是否调用preventDefault[是否存在?]
-
-
Event对象var event=new Event('type', options{'bubbles','cancelable'})- 属性
-
bubbles是否冒泡[默认不冒] -
eventPhase0没发生/1捕获/2到达节点/4冒泡 -
cancelable是否可以取消[Event对象构造的默认不行]/preventDefault能取消就取消/cancelBubble阻止传播/defaultPrevented是否调用过👆 -
target原始触发节点/currentTarget正在通过的节点 type-
timeStamp毫秒值,事件发生时间 -
isTrue是否为用户产生[否:脚本写的] -
detail用户界面事件具有,取决于具体事件
-
- 方法
-
preventDefault()取消浏览器的默认事件,但不阻止事件传播 stopPropagation()-
sropImmediatePropagation()阻止元素上的剩余事件监听函数被执行 -
composedPath()触发节点及冒泡经过的所有上层节点组成的数组
-
-
各种事件:
-
鼠标:
mouseenter/leave不在进入/离开子节点中重复触发/mouseover/out会 -
键盘:按着不放
keydown与keypress交替出现/code按下的键/key按下的特殊字符 -
进度:
ajax请求也可以添加事件监听函数 -
表单:
submit事件/InputEvent对象:data/inputType/dataTransfer -
触摸:触屏中默认同时触发鼠标事件/
screen/client/pageX/Y相对于屏幕/浏览器/当前页面/radiusX/Y/rotationAngle:精确描述触摸/TouchEvent.touches/changedTouches/targetTouches→TouchList/touchstart/end/move/cancel/target -
拖拉
drag/drop[ondrag=event.preventDefault()]-
DragEvent接口:多重继承自Event接口和MouseEvent接口 -
DataTransfer接口- 属性
-
dropEffect:copy/move/link/none一般在dragenter/over的监听函数中设置 effectAllowed-
files:接收拖拉文件,详见test_file.html&js -
types:拖拉的数据格式,MIME值,text/plain/text/html/text/uri-list/image/jpeg/... -
items:返回DataTransferItemList实例[length/ add(data,type)/add(file)/remove(index)/clear()/]→DataTransferItem实例[kind[string/file]/type/getAsFile() /getAsString(callBack)]
-
- 方法
-
setData('type','data'):可再来一份纯文本 getData('type')-
clearData('type')[无法移除拖拉文件] setDragImage(img节点,鼠标相对于图片左上角的x,y)
-
- 属性
-
资源/session/网页状态/窗口/剪贴板/焦点/CustomEvent
-
beforeunload/unload/load[加载缓存时不触发]/error/abort -
session:历史事件- 缓存:
pageshow[第一次加载/缓存加载都触发]/persisted:是否为缓存/pagehide离开当前页面,页面内容会保存在缓存中/persisted:是否保存→否:此后执行unload监听函数→只在history对象发生变化时触发 -
popstate事件:history对象显示切换:鼠标/history.back/forward/go()/属性:state -
hashchange:URL中#及以后部分改变→不重新加载页面但会产生新的历史记录→前端!router!/属性:oldURL/newURL
- 缓存:
-
DOMContentLoaded[资源可能还没加载完]/readystatechange:DOM/AJAX/loading/interactive/complete -
scroll:throttle详见test_file.js/resize/fullscreenchange/ error event[ClipboardEvent实例:cut/copy/paste]. clipboardData[DataTransfer实例]event[FocusEvent实例:focus/blur[只捕获:addEL:t]/focusin/out]. target/relatedTarget[前2:null/后2:节点]-
CustomEvent接口:用于在触发事件时传入数据:new CustomEvent('type',options:{'detail':'数据'})
-
-
鼠标:
12 条件/循环
类似C
-
if ()else ifelse -
switch()case[不同情况共享代码:上下各一行]default- 比较使用
===,不发生类型转换 - 最好使用对象结构代替
- 比较使用
-
while()/do{}while();先判断后执行/先执行后判断 for (;;)-
for (属性 in 对象)依次返回对象的可枚举属性 -
break跳出循环/continue跳过/终止本轮,开始下一轮循环 - 标签
label标记位置,可示意break/continue语句跳到哪里,可跳出任何代码块
13 错误
-
Error对象:var err=new Error(meaasage[, name, stack]); - 原生错误:
SyntaxError语法错误/ReferenceError引用错误(对象不存在/无法被赋值)/RangeError/TypeError(new了原始对象/调用不存在的方法)/URLError可套用👆 -
throw 任何值→程序终止 -
try{} catch(){} [finally{}]catch跑完/出现throw/return→finally→终端执行[并returnreturn和throw会互相覆盖]
14 控制台用法
-
console.log/info[/debug]()- 占位符基本同C+
%o对象的连接+%cCSS格式字符串 - 输出一个对象,会显示构造函数
- 占位符基本同C+
console.wran/error()-
console.table()以表格显示复合类型数据 -
console.count([para])统计自己被调用的次数:para: count -
console.dir/dirxml(obj)对象检查-
console.dir(DOM对象)显示DOM对象的所有属性 -
console.dirxml(DOM对象)以目录树显示DOM节点
-
-
console.assert(条件, 错误信息)条件==false时,提示错误信息但不中断程序 console.time&timeEnd()console.group/groupCollapsed/groupEnd()-
conosole.tace()返回代码在堆栈中的调用路径/console.clear()清除控制台所有输出 - 之后学:命令行API
-
debugger;存在除错工具则自动停下,自动打开源码页面
14 严格模式
-
'use strict'- 放在脚本第一行
- 合并是与不是严格模式的脚本,可以将严格模式的放进匿名闭包/自调用/立即执行的匿名函数
- 报错无效操作
- 更改了只读属性/删除了不可配置属性
- 只给属性设置
getter - 尝试更改对象被冻结的部分
- 将
eval/arguments作为标识名 - 函数出现重名参数
- 使用
0前缀标识八进制数
- 报错不安全操作
- 不显式声明全局变量
- 函数内部的
this指向了window而非它所在的对象(并且this指向null/undefined时,不会自动把this指向window) - 删除除了对象的可删除属性的变量
- 限制动态绑定
- 不能使用
with -
eval()中为独立的作用域 - 除了调用函数,无法改变
arguments数组
- 不能使用
15 性能优化
16 异步操作
单线程
-
同步/异步任务
同步
-
异步[挂起]←循环检查机制:事件循环👉类似操作系统检查
I/O操作-
操作模式
- 回调函数[必须要有]:在函数1结尾时调用函数2,保证运行顺序
- 事件监听:
-
function f1(){...f1.trigger('事件')}&f1.on('事件',f2) - 去耦合[coupling]但运行流程不清晰
-
- 发布/订阅模式/观察者模式(有
PV操作内味了)
jQuery.subcribe('事件',f2); function f1(){ //... jQuery.publish('事件'); //... } jQuery.unsubcribe('事件',f2); -
流程控制
- 串行:做个数组放
return里递归着删 - 并行:做个数组
forEach()它 - 结合:规定最高并行数量:函数套在
lquncher()里,设置running<limit才在函数中调用launcher()
- 串行:做个数组放
-
AJAX:Asynchronous Javascript And XML(可扩展标记语言)[也可能用纯文本或者JSON传数据],详见BOM- 事件→
js创建XMLHttpRequest对象→对象对服务器发送请求→服务器处理并响应→js读取→js更新页面等 - 请求
- 事件→
-
-
定时器
-
setTimeut(函数[回调函数]/'代码', 延迟执行毫秒数[default=0][, 回调函数的参数])返回定时器编号[可用于取消],定时器编号自动递增$('textarea').on('keydown',debounce(ajaxAction,2000))//"防抖" function debounce(fn,delay){ var timer=null; return function(){ var context=this; var args=arguments; clearTimeout(timer); timer=setTimeout(function (){ fn.apply(context,args); },delay); }; } setInterval()用法同上,间断(毫秒数-运行时间)无限次执行clearTimeout/clearInterval(定时器编号)会被事件循环的延迟(
sleep(n)等)干扰,此后在等待后继续生效-
setTimeout(f,0)- 在同步任务结束后进入事件循环,即在下一事件循环的开始执行
-
应用
- 使子元素的回调函数成为
setTimeout()中的函数,使子元素回调函数不会自动先于父元素回调函数触发 - 把浏览器同步任务做完再干的事放进
setTimeout() - 把耗时的
js操作放进setTimeout()里递归
- 使子元素的回调函数成为
-
-
Promise对象var p1=new Promise(f1); p1.then(f2);- 目的:改善
f2作为回调函数写在f1里作为回调函数时古怪的代码 - 状态
-
pending→fulfilled:Promise实例传回revolve👇中的值 -
pending→rejected:Promise实例抛出reject👇中的错误
-
- 构造函数
-
resolve(value):fulfilled -
reject(new Error()):rejected
-
- 实例方法
-
then(成功时的回调函数, 失败时的回调函数)返回一个Promise对象,支持写一串 - 调用
then()的Promise对象的返回值/前一个then()中回调函数的返回值(Promise对象)的返回值,会成为后一个then()中的回调函数的参数
-
- 微任务:追加到本轮事件循环,早于异步任务
17 HTML DOM/文档对象模型
-
定义
-
HTML的标准对象模型和编程接口/获取/添加/更改/删除HTML元素的标准 - 将
HTML元素作为对象/访问它的属性/方法/事件 - 浏览器根据
DOM模型将HTML之类的结构化文档解析、组成DOM树
-
-
节点/接口
DOM的最小组成单位,继承自节点对象Node-
var node=节点: 引用- 常量:9
DOCUMENT_NODE/1ELEMENT_NODE/2ATTRIBUTE_NODE/3TEXT_NODE/11DOCUMENT_FRAGMENT_NODE/10DOCUMENT_TYPE_NODE/8COMMENT_NODE - 属性
-
nodeType👆常量之一 -
nodeName根据节点返回#document/大写标签名/属性名/#text/#document-fragment/文档类型/#comment -
nodeValueText/Comment/Attr对应其文本值,其它结果为null -
textContent忽略所有HTML标签识别,读/写所有文本内容 -
baseURI绝对路径 -
ownerDocument顶层文档对象,不可用于文档节点 -
next/previousSibling/parentNode/Element/first/lastChild/childNodes -
isConnected节点是否在文档中
-
- 实例方法
append/removeChild(Node)replaceChild(newNode, oldChild)hasChildNode(Node)-
cloneNode(true)[会缺被克隆节点的事件回调函数/克隆完需要被添加] insertBefore(Node[插在→之前, refeNode/null:插最后])-
contains(Node)Node为调用节点/的子/后代节点/compareDocumentPosition(Node)Node在调用节点的相同节点/不同文档/前面/后面/包含/被包含/浏览器内部:返回0/1/2/4/8/16/32,多种情况并存则相加;使用时需要进行位运算 -
isEqual/SameNode()类型属性子节点是否相同/是否为同一节点 -
normalize()处理当前节点的所有文本子节点,空的删除相邻的合并 -
getRootNode()可用于文档节点
- 常量:9
-
节点组:接受
DOM属性返回的节点集合-
NodeList:各类都可以有- 来自:
Node.childeNodes()[会返回动态集合,DOM改变则随之改变]/document.querySlectorAll()[返回静态集合]等方法 - 可以用
var nodeArr=Array.prototype.slice.call(NodeList)转换为数组 - 属性:
length - 实例方法
forEach()-
item()/下标 -
keys()/values()/entries()
- 来自:
-
HTMLCollection:只能有element节点lengthitem()-
namedItem('id/name的值')返回id/name值同参数的节点
-
-
Parent/ChildNode-
ParentNode:拥有子节点的节点- 可能有子节点的节点:
element/document/documentFragment childrenchildElementCountfirst/lastElementChilrenappend/prepend()-
normalize()合并Text节点
- 可能有子节点的节点:
-
ChildNode:拥有父节点的节点remove()-
before/after(Node)在当前结点之前/之后插入参数节点 replaceWith()
-
-
文档
document顶层节点/手册- 获取
[window.]document-
iframe框架网页的iframe.contentDocument XMLHttpRequest.responseXML{innerNode}.ownerDocument
- 属性
- 快捷方式
- 节点集合:
HTML对象选择器标签同名s[下标/'id'/'name']返回HTMLCollection - 文档静态信息:
[document]URL/doman/location/... - 文档状态:
hidden/visibilityState/readyState[loading→interactive→complete] cookie-
designMode可编辑:on/off currentScriptimplementation.createDocument()/HTMLDocument()/DocumentType()
- 实例方法
open()/close()write('HTML代码')/writeIn()- 查找
HTML元素getElementById('id')/getElementsByName('name')/getElementsByClassName('name1 name2 ...')/getElementByTagName('tag') -
CSS对象选择器querySelector/querySelectorAll('CSS选择器')但无法选择伪元素和伪类 - 添加/删除
remove/append/replaceChild('element')-
adoptNode(externalNode)/importNode(externalNode, deep?)只改变了归属,还需要用👆插进文档树 -
createElement('element')/createTextNode()[不转义双引号]/createAttribute/Comment /DocumentFragment() -
create/dispatchEvent('type{UI/Mouse/...Event}')/add/removeEventListener
- 遍历
-
createNodeIterator(root, NodeFilter.type)- type:
SHOW_ALL/ELEMENT/TEXT/COMMENT - 返回
NodeFilter实例→.next/previousNode()遍历并返回?所在节点后指向下一个/指向上一个后返回
- type:
-
createTreeWalker(root, NodeFilter.type)返回TreeWalker实例
-
element[s]FromPoint(x, y)hasFocus()-
query:
execCommand('bold/createLink/delete/italic/insertHTML/...', false[recommended], input[辅助内容?])/queryCommandSupported ('exex命令')/queryCommandEnabled()
- 获取
DocumentType-
ElementHTML标签/元素改变
innerHTML/[attribute]/setAttribute(attr,value)/style.[property]-
属性
-
**属性相关 **
-
id/tagName/dir/accessKey[转移focus快捷键]/draggable/lang/tabIndex[规定Tab键遍历时的顺序]/title[鼠标悬浮提示框]/... -
[attribute]for→htmlForclass→className -
attributes[.属性名/['属性名]'/[下标]]拥有name和value属性 - 自定义属性
data-*[不能有大写可改用-]dataset.[data-后的内容]读取data-开头的属性,在JS中用驼峰写法,HTML中用-连接
-
状态相关
hidden[CSSs的display设定高于👈]/isC/contentEditable-
className返回以空格分隔的字符串/classList返回类似数组的对象classList.:add/remove/contains/toggle不存在则加入存在则移除('class')/item(下标)/toString() outerHTML包括标签的HTML代码 无父节点会报错/innerHTML/textContentstyle[.property]clientHeight/Weight包括padding的块级元素高/宽[body网页/documentElement视窗]/clientLeft/Top左/上border宽度scrollHeight/Weight适用所有元素,包括padding/伪元素/scrollLeft/Top滚动条宽/高offsetParent返回最靠近当前元素,忽略display: none和position: fixed的那些/offsetHeight/Weight包括整个盒子和滚动条/offsetLeft/Top当前元素左上角相对于offsetPerent的水平/垂直位移children/childElementCount只包括元素类型子节点first/lastElementChild/next/previousElementSibling
-
-
实例方法
属性相关
get/set/has/removeAttribute()/getAttributNames()/hasAttributes()CSS选择器querySelector('选择器1, 选择器2, ...')全局搜索选择器/querySelectorAll()/closest('选择器')离选择器最近的符合要求的当前或祖先节点/matches('选择器')元素节点下搜索
getElementsByClass/TagName-
事件相关→
EventTarget接口- 添加/删除事件监听器
add/removeEvenListener('事件', 处理函数,false) dispatchEvent(Event对象)- 添加事件处理程序
事件=funcion (){//...}
- 添加/删除事件监听器
scrollIntoView([default:true/false])元素与当前可见区域顶部/底部对齐[用于置顶导航栏?]-
getBoundingClientRect()返回rect对象,包含CSS盒子信息,属性皆来自继承:x/y元素左上角相对于视口/height/width.left/right/ top/bottom/绝对👉window.scrollX/Y+left/topgetClientRects()对内联元素返回行数,会考虑被HTML忽略的换行 -
insertAdjacentElement(position{before[当前结点之前,需要父节点]/afterbegin[内部第一个子节点之前]/before/afterend}, element)insertAdjacentHTML/Text(position, text)不转义,不可用于处理用户输入内容 remove()/focus/blur()/click()
Attribute-
Text[对象]- 属性
data[=nodeValue]/wholeText/其它同Node - 方法
-
appendData('str')/deleteData(位置, 子串长度)/insertData(位置, 'str')/replaceData(位置, 长度, 'str')/subStringData(位置, 长度) -
splitText(位置)分割位置后方的字符串为新节点 - 其它同
Node
-
- 属性
Comment-
DocumentFragment不属于文档、可灵活使用的DOM对象- 比
Node多了:children/first/lastElementChild/childElementCount
- 比
-
节点树
节点树 -
表单
- 约束验证DOM:
document.getElementById('id')为<input>-
checkValidity()/setCustomValidity() -
validity/validationMessage/willValidate
-
- 约束验证DOM:
-
CSS操作- 用
get.set/removeAttribute()方法更改style属性 -
CSSStyleDeclaration接口/对象:Element.style/CSSStyle.style/window.getComputedStyle()最终样式信息可调用- 返回绝对单位[
px/#rgb值]/简写[margin/font等]无效/styleObj['a-b']/styleObj.aB -
.CSS属性需要改成驼峰写法/.cssText='str'+...不需要改写 -
length返回样式声明数量 -
parentRule返回CSSRule实例[如果有] -
getPropertyPriority('属性名')设置important优先级则返回 getPropertyValue('属性名')item(下标)-
removeProperty('属性名')/setProperty('属性名'[, 'value', 'important'])
- 返回绝对单位[
- 模块侦测:
HTML元素.style['属性名[-/驼峰写法皆可]']浏览器支持返回string/不支持返回undefined/浏览器的CSS前缀:mos/webkit/o/ms/khtml -
CSS对象CSS.escape(含有需要转义的特殊字符的值)CSS.supports('属性','值'/'CSS语句[不带分号]')
-
StyleSheet接口/对象,可以[下标]读取-
document.styleSheets/elem.sheet返回此对象 - 属性
disabled[只能在js代码里设置]/href/media:screen/print/ all/title/type:text/css/parentStyleSheet/cssRules.items(下标)/[下标][.cssText/style.property='value']/通过@import/加载输入的样式表:ownerNode:link/style/ownerRule - 实例方法
-
insertRule('CSS语句', 插入位置[=0])最好放进try/catch deleteRule(语句位置)
-
-
-
CSSRuleList接口/对象- 由
sheet.cssRules得到 -
CSSRule接口/对象- 属性
cssText-
parentStyleSheet返回所属的StyleSheet对象 -
parentRule返回父规则 -
type普通/CSSStyleRule/@import/@media[可用于区分电脑/手机屏幕]/CSSMediaRule/@font-face-
CSSStyleRule接口/对象: 属性selectorText/style -
CSSMediaRule接口/对象: 属性media返回MediaList实例/conditionText
-
- 属性
- 由
-
windows.matchMedia('MediaQuery条件语句: mediatype and/or/only (feature)')返回MediaQueryList实例- 属性
-
media返回条件语句 -
matches返回是否符合条件 onchange=监听函数function(MediaQueryListEvent实例){//...}
-
- 实例方法
add.removeListener(监听函数)
- 属性
- 用
-
监听
DOM:Mutation Observer API不是同步触发的事件[不是指事件循环],是异步,以
MutationRecord数组记录所有DOM操作,全部结束/任务队列清空后触发var observer=new MutationObserver(回调函数:function (变动数组, observer){//...});-
实例方法
-
observe(DOM节点/target, 变动)启动观察器- 变动:一个对象,至少有一下一个键值对
- 键:
childList观察子节点/attributes观察属性/characterData观察内容/文本/subtree是否观察节点所有后代/attribute/characterOldV alue/attributeFilter指定观察属性的数组 - 值:功能是否开启
- 键:
- 对同一个节点做多个变动观察,观察器相同则无效,不同则覆盖
- 变动:一个对象,至少有一下一个键值对
-
disconnect()停止观察/takeRecords()停止观察并返回未处理变动数组
-
-
MutationRecord对象- 属性:
type/target/add/removeNodes/previous/nextSibling/attributeName/oldValue[只对attribute/characterData有效]
- 属性:
-
封装的
DOM观察函数(function(win){ 'use strict'; var listeners = []; var doc = win.document; var MutationObserver = win.MutationObserver || win.WebKitMutationObserver; var observer; function ready(selector, fn){ // 储存选择器和回调函数 listeners.push({ selector: selector, fn: fn }); if(!observer){ // 监听document变化 observer = new MutationObserver(check); observer.observe(doc.documentElement, { childList: true, subtree: true }); } // 检查该节点是否已经在DOM中 check(); } function check(){ // 检查是否匹配已储存的节点 for(var i = 0; i < listeners.length; i++){ var listener = listeners[i]; // 检查指定节点是否有匹配 var elements = doc.querySelectorAll(listener.selector); for(var j = 0; j < elements.length; j++){ var element = elements[j]; // 确保回调函数只会对该元素调用一次 if(!element.ready){ element.ready = true; // 对该节点调用回调函数 listener.fn.call(element, element); } } } } // 对外暴露ready win.ready = ready; })(this); // 使用方法 ready('.foo', function(element){ // ... });
18 BOM
-
浏览器环境
-
JS嵌入:<script>/URL协议:<a href="javascript:语句1;语句2;..."></a> -
<script>- 将之放在页面底部,防止假死,防止调用没有生成的
DOM - 脚本运行顺序根据标签出现先后决定
-
defer:不可用于内置脚本和动态生成的script标签,加入后,脚本在DOMContentLoaded事件出发前/读取完</html>标签后执行 -
async:加入后,在遇到此标签时开启另一个进程下载脚本,下载完了就执行,无法以标签顺序保证先后,会覆盖defer的作用 - 动态加载:
['a.js','b.js].forEach(//...)详见loadScript.js - 加载协议:默认
HTTP:src='a.js'/指定:src='http://a.js'/根据页面本身决定:src='//a.js'
- 将之放在页面底部,防止假死,防止调用没有生成的
-
-
浏览器组成
- 渲染引擎:
Webkit/...-
HTML→DOM&CSS→CSSOM/render tree/layout/flow&paint - 优化:减少重流重绘次数
-
DOM一起写 - 缓存
DOM - 用
CSSclass一次性改样式 - 使用虚拟
DOM库 - 使用
absolute/fixed定位动画 - [?]用
documentFragment操作DOM - [?]用
window.requestAnimationFrame(function ...)容纳DOM操作
-
-
-
JS解释器/引擎:V8/...- 即时编译
JIT:代码编译为字节码并缓存,运行时只编译用到的语句,并且编完了缓存
- 即时编译
- 渲染引擎:
-
window对象-
属性
-
name浏览器窗口名,只要不关都会被记忆 -
closed一般用于检查window.open()制造的弹窗是否被关闭/opener一般用于切断与父窗口[打开窗口的窗口]的联系,防止被父窗口URL被修改 window.self/window===true-
frames返回页面中所有窗口:<frame>/<iframe>/lendth返回页面中窗口的个数/[?]frameElement -
top/parent获取顶层/父窗口 -
status状态栏文本[不被支持] -
devicePixelRatio:物理像素CSS像素比,越大越高清 -
isSecureContext是否为加密环境/用了HTTP协议 -
screenX/Y/innerHeight/Width窗口可见部分高宽,包括滚动条/outerHeight/Width浏览器窗口高宽/scrollX/Y/pageX/YOffset浮点数,水平/垂直滚动距离 -
locationbar地址栏/menubar菜单栏/scrollbars/toolbar/statusbar/personalbar - 全局对象属性
document/location:URL/navigator:环境/history:浏览历史/local/sessionStorage/console/screen
-
-
方法
alert('strMsg')/var result=window.prompt('strMsg'[,默认输入]):用户输入/默认值/null/var result=window.confirm('strMsg'):true/falsevar popup=window.open('url','windowName'[,windowFeatures])返回新窗口的引用/popup.close()关闭open()制造的窗口/stop()停止加载资源moveTo/By(x,y)移动open()创建且只有一个标签页的窗口到某位置/移动某距离resizeTo/By(x,y)缩放绝对/相对大小scroll[To](x,y)/(options:{top=y,left=x,behavior:smooth, instant,auto[default]})/scrollBy(x,y)/element.scrollTop/Left/IntoView()print():if(tyepof window.print==='function'){//...}window(实例).focus/blur()getSelection()读取被选中的文本-
requestAnimationFrame(callback{performance.now()距离网页上次加载的时间})在浏览器下一次重流时执行回调函数并重绘[间隔16ms],返回一个整数,可以用cancelAnimationFrame()取消var element=document.getElementById('animate'); element.style.position='absolute'; var start=null; function step(timestamp){ if (!start) start=timestamp; var progress=timestamp-start; element.style.left=Math.min(progress/10,200)+'px'; if(progress<2000){ window.requestAnimationFrame(step); } } //视觉效果很平滑同时没有造成过多的重绘 window.requestAnimationFrame(step); reqyestIdleCallback(callback{IdleDeadline:{didTimeout& timeRemaining()}}[,options:{timeout最长推迟毫秒数}])等系统资源空闲时执行回调函数,返回一个整数,可以用cancelIdleCallback()取消
-
事件
window.onload=function(){//...}window.onerror=function(message,filename,lineno,colno,error)- 额外的事件监听属性
-
窗口
-
top/parent/self -
frame.contentWindow.document/contentDocument/frameElement window.frames[i]/id.document
-
-
-
navigater对象- 环境信息:浏览器+系统
- 属性
-
userAgent浏览器/plugins插件/platform操作系统 -
online/offline -
language[s]/languagechange -
getCurrentPosition()/watchPosition()/clearWatch() -
cookieEnable浏览器是否能用cookie
-
- 方法
-
javaEnabled()是否能运行Java Applet小程序 -
sendBeacon()异步发数据
-
-
screen对象显示设备信息
-
属性:
height/wodth/availHeight/Width/pixel/colorDepth/orientation屏幕方向:type:landscape/portrait横竖-primary/secondary正倒
-
cookie- 保存状态信息:
session管理/个性化/追踪用户分析行为 - 元数据:名字/值[信息]/到期时间/所属域名/生效路径
- 服务端要求浏览器保存
cookie:HTTP头信息中添加:Set-Cookie:<cookie-name>=<cookie-value>;属性=<value>,一个一行- 修改:
key/domain/path/secure都匹配 - 否则生成新
cookie,最匹配的排前面
- 修改:
- 浏览器发送:
HTTP头信息中添加:Cookie:<cookie-name1>=<cookie-value1>;...[不知道属性和设置它的域名] - 属性
-
Max-Age=存在秒数/Expires=作废时间(Date.prototype.toUTCString())-
Max-Age优先 - 都不设置/写成
null:浏览器关了就删Session Cookie
-
-
Domain=附带cookie的域名/默认当前不带子域名/Path=附带cookie的路径/只要当前路径的一部分有它就附带 -
Secure 用HTTP协议[加密]才发cookie/HttpOnly 只有发HTTP请求时服务器才拿到cookie/document.cookie/XMLHttpRequest/Request API都不行 - 限制第三方
cookie:SamSite- 滥用:
CRSF攻击[防止:发随机token]/用户追踪 -
Strict跨域则不发cookie -
Lax链接/预加载/GET表单发 -
None:Set-Cookie:name=value;SamSite=None;Secure
- 滥用:
-
-
document.cookie- 读:返回当前网页没有
HttpOnly的cookie组成的数组 - 写:
path绝对路径/domain一级域名/max-age/expires - 删除:把
expires设成过去日期
- 读:返回当前网页没有
-
XMLHttpRequest对象/ajax
- 保存状态信息:


