文章目录
学习资源:
es6新特性:ES6经典入门到进阶 - 网易云课堂
JavaScript
一、JS浏览器发展史,介绍,入门
1、JavaScript浏览器发展史
浏览器两大组成:
shell(外观) 用户能操作的部分
内核 (看不到的)
渲染引擎
js引擎(处理js代码)
其他模块
JS:客户端脚本语言
1、解释性语言 (js、PHP、Python)
编译性(C、C++):通篇翻译,生成特定的文件 优点:快 不足:移植性不好(不跨平台)
注:Java 有虚拟机jvm .java–javac–编译–.class(可跨平台)
解释性:逐句翻译,不生成特定的文件 优点:跨平台 不足:稍微慢
2、单线程
3、ECMA标准(语法标准)
JS三大部分:ECMAScript、DOM、BOM
**JS执行队列:**轮转时间片(进程-线程)
2、js介绍、入门
主流浏览器及其内核:
浏览器 | IE | Chrome | Firefox | Opera | Safari |
---|---|---|---|---|---|
内核 | trident | webkit/Blink | Gecko | presto | webkit |
如何引入js:
1、页面内嵌script标签
2、外部js文件
<script scr=""></script>
注:结构、行为、样式相分离,故通常采用外部js文件
js基本语法:
变量(variable) var
var a=10, b=20, c, d;
命名规则:
1、_、字母、$开头
2、可以包含字母、数字、_、$
3、不可以用关键字、保留字
数据类型(弱类型语言):
原始值:number string Boolean undefined null
引用值:array object function date RegExp…
区别:
原始值 引用值 存放位置 栈(stack):先进后出 堆(heap):存储地址 赋值形式不同 基本语法:
语句结束加“;”
js语法错误会引发后续代码终止,但不会影响其他js代码块
js运算符:
计算运算符:
“+” :任何类型数据与字符串连接都是字符串类型
“-” “*” “/” “%” “=”
优先级"="最弱,“()”较高;
++
比较运算符(返回结果为Boolean):
< > == !=
字符串比较的是ASCII码 0:48 A:65 a:97
特例:a=NaN==NaN false
逻辑运算符: && || !
undefined,null,NaN,"",0,false==>false,其余为true
&&: 有两个表达式,第一个为转换为bool,若为真,返回第二个;若为假,返回第一个 var a=1&&2; var a=0&&2; //a=2 //a=0; 全真才为真,一假都为假 &&可以作为中断作用: 2>1 && document.write("hello");//类似if语句 data && fn(data);
二、条件语句 循环语句
条件语句
if(条件){
}
if(){
}else if(){
}else{}
循环语句
1 for
2 while
3 do{
}while()
条件语句补充:
switch case
switch(条件){
case 1:
...
break;
}
break
continue:终止本次循环,进行下一次循环
三、typeof,类型转换
数组(array)
var arr=[1,2,f,"asd",undefined];
arr[i]
arr.length
数组循环
- for
- while
- forEach 简化版for
- map
- 正常情况下,需要配合return
- 若是没有return,相当于forEach
- filter 过滤。过滤一些不合格的“元素”。如果回调函数返回true,就留下来
- some/every 查找匹配。some只要有一个匹配,即返回true;every需要所有匹配,返回true,否则返回false
- reduce/reduceRight
let arr = ['apple', 'banana', 'orange', 'tomato'];
arr.forEach((value, index, array) => {
console.log(value, index, array);
});
let arr2 = [
{
title: 'a',
read: 100,
hot: true
},
{
title: 'b',
read: 200,
hot: true
},
{
title: 'ca',
read: 300,
hot: true
}
];
let newArr = arr2.map((value, index, array) => {
console.log(value, index, array);
return "1";
});
console.log(newArr);
let arr3 = (function () {
let arr = [];
for (let i = 0; i < 100; i++) {
arr.push(i);
}
return arr;
}());
console.log("-----");
console.log(arr3);
let newArr1 = arr3.filter((val) => {
return val % 7 === 0;
});
console.log("*********");
console.log(newArr1);
let a = arr.some((value) => {
return value === "banana";
});
let b = arr.every((value) => {
return value === "banana";
});
console.log(a);
console.log(b);
let sum = arr3.reduce(((previousValue, currentValue, currentIndex, array) => {
return previousValue + currentValue;
}));
console.log(sum);
数组常用方法
- push/pop
- Array.from(arr):作用:把类数组(获取一组元素,arguments…)转换为数组;或者用户复制数组
- Array.of(arr):把一组数据转为数组(不常用)
- slice():裁剪数组
- find():查找。找出第一个符合条件的数组成员。如果没有找到,返回undefined
- findIndex():找出第一个符合条件的数组下标
对象(object)
var den={ 属性名 属性值 lastName : "Deng", age : 40, handsome : false,}den.age=25;console.log(den.age);
面向对象:
面向对象=对象+类+继承+消息通信
对象:对象是由一组属性值和在这组值上的一组操作组成;数据+对数据的操作
类:具有相同属性值和服务的对象归到一个类;每一个对象称为该类的实例,其具有相同的服务
消息通信:各个类的对象之间通过消息进行通信。
typeof:
返回数据类型:number,string,boolean,object,undefined,function
类型转换:
显式类型转换:
Number();//不能转的转为NaNparseInt(data,进制);//以目标进制为基,转换为十进制 //从数字开始,读取到第一个非数字位;parseFloat();//读取到第一个非小数点的非数字位;String();toString();//undefined/null不能用toStringboolean();
隐式类型转换
isNaN();-->number();++/-- + -...//-->number()
不发生类型转换:
=== !==
eg:
typeof返回类型:number,string,Boolean,undefined,objecttypeof(typeof(a));//string特殊:typeof(null) object
其他类型转Boolean:
- number:0或NaN为假,其他为真
- string:除了空字符串(""),其他都是true
- null&undefined:都是false
- 对象:所有对象都是true
四、函数
函数
函数声明:function 函数名(){}函数表达式:(忽略函数名)var 函数名= function (){}调用 函数名();
参数
function sum(a,b){ 形式参数-->形参 //var a;var b; var c=a+b; document.write(c); 实际参数-->实参}sum(1,2);
形参、实参个数可以不匹配
天生不定参,形参可以比实参多,实参也可以比形参多
arguments 这个是实参列表
function sum(a){ //argument--[11,2,3] argument.length //sum.length }sum(11,2,3)
函数结束条件:return
作用:结束函数;返回值
若未显式地设置函数的返回值,则函数会默认返回一个undefined值
若需要函数返回多个值,则只有将值组合成一个对象或数组进行返回
return;return a;return [a,b]
五、递归 预编译
递归注意两点:
1、找规律
2、找出口
js运行三部曲:
1、语法分析
2、预编译 函数声明整体提升 变量 声明提升
3、解释执行
1、imply global 暗示全局变量:即任何变量,如果变量未经声明就赋值,此变量就为全局变量所有
2、一切声明的全局变量,都是window的属性 var a=123==>window.a=123;
3、window是个对象,且是全局对象 GO(Global Object)===window
函数 预编译四部曲:
1、创建AO对象 Activation Object(执行期上下文)
2、找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
3、将实参值和形参统一
4、在函数体里面找函数声明,值赋予函数体
注:先创建GO,运行到函数体,再创建AO
六、闭包
作用域、作用域链
[[scope]]:每个JavaScript函数都是一个对象,对象中有些属性我们可以访问,但有些不可以,这些属性仅供JavaScript引擎存取,[[scope]]就是其中一个。
[[scope]]指的就是所说的作用域,其中存储了运行期(执行期)上下文(AO)的集合。
作用域链:[[scope]]中所存储的执行期上下文对象的集合,这个集合呈链式连接,我们把这种连接叫做作用域链。
函数执行完后,其本身的AO会销毁
查找变量:从scope顶端开始查找
function a(){ function b(){ ... }}
a定义时,只产生GO;a执行时,再在顶端产生AO
b产生时,继承a的GO和AO,b执行时,再顶端产生自己的AO
闭包:
当内部函数被保存到外部时,将会生成闭包。闭包会导致原有作用域链不释放,造成内存泄露。
闭包的作用:
实现共有变量 eg:函数累加器
可以做缓存(存储结构)
可以实现封装、属性结构化
模块化开发,防止污染全局变量
立即执行函数:(执行完函数立即释放)
只有表达式才能被执行
(functon (){}());或(functon (){})();(function (a,b,c){ var d=a+b*3+c*5-2; return d;}(1,2,3))
**解决闭包的方法:**用立即执行函数,闭包的方式解决闭包
两个闭包例子:
function a(){ function b(){ var bb=234; document.write(aaa); } var aaa=123; return b;}var glob=100;var demo=a();demo();
function text(){ var arr=[]; for(var i=0;i<10;i++){ arr[i]=function(){ document.write(i+" "); } } return arr;}var myArr=text();for(var j=0;j<10;j++){ myArr[j]();}解决方法(立即执行函数)function text(){ var arr=[]; for(var i=0;i<10;i++){ (function(j){ arr[j]=function (){ document.write(j+" "); } }(i)) } return arr;}var myArr=text();for(var j=0;j<10;j++){ myArr[j]();}
七、对象,包装类,原型
对象
var Deng={ name:"deng", sex:40, health:100 smoke:function (){ console.log("dsd"); this.health--; } }
对象属性的增删改查
查:Deng.name;增:Deng.wife="liu";改:Deng.sex="female";删:delete Deng.name;
对象的创建方法
1、var obj={} plainObject 对象字面量/对象直接量2、构造函数(构造函数命名遵循大驼峰式规则,即所有单词首字母均大写) 1)系统自带的构造函数 new Object() var obj=new Object();==>var obj={}; 2)自定义 function Car(){ this.name = "BMW"; this.height = "1400"; this.health = 100; this.run = function (){ this.health--; } } var car1 = new Car();
构造函数内部原理
1、在函数体最前面隐式的加上this={}2、执行this.xxx=xxx;3、隐式的返回this
包装类
原始型赋属性,需要调用包装类。包装类用完后立即deletenew Numbe/String/Boolean();
原型,原型链
原型定义:原型是function对象的一个属性,它定义了构造函数制造出的对象的共同祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。
prototype --原型
- 利用原型特点和概念,可以提取共有属性
- 对象如何查看原型 – >隐式属性 _proto_
- 对象如何查看对象的构造函数 – > constructor
Person.prototype.property="men";或Person.prototype={}Person{}
prototype默认隐式属性
__proto__:Person.prototype;constructor构造器,指向对象的构造函数Person.prototype{ constructor:Person(){} }
原型链
原型链顶端Object.prototype
var object=Object.create(原型);
绝大多数对象最终都会继承自Object.prototype,除了Object.create(null);
eg:
var num = 123;num.toString();-->new Number(num).toString();Number.Prototype.__proto__ = Object.prototype
call/apply
作用,改变this指向 借用别人的函数实现自己的功能
区别,传参列表不同
call需要把实参按照形参的个数传进去apply需要传一个argumentsPerson.call(obj,age,sex,hobbit);Person.apply(obj,[age,sex,hobbit]);
eg:
function Person(name, age, sex) { this.name = name; this.age = age; this.sex;}function Student(name, age, sex, tel, grade) { Person.call(this, name, age, sex); this.tel = tel; this.grade = grade;}var student = new Student("tom", 45, "male", 123, 2020);
八、继承模式,对象枚举
继承模式
- 传统形式 --> 原型链
- 过多的继承了没用的属性
- 借用构造函数
- 不能继承借用的构造函数的原型
- 每次构造函数都要多走一个函数
- 共享原型
- 不能随便改动自己的原型
- 圣杯模式
圣杯模式:
function inherit(Target,Origin){ function F(){}; F.prototype=Origin.prototype; Target.prototype=new F(); Target.prototype.uber=Origin.prototype;//target的超类}inherit(Student,Person);var student=new Student();
注:模拟jQuery,实现方法的连续调用:
return this;
属性的拼接
obj.name --> obj["name"];eg:var num = 1;return this["name" + num];
对象枚举
for(var prop in obj){ //forEach console.log(prop); console.log(obj[prop]);}obj.hasOwnProperty(); //判断属性是否是对象自身的instanceof A instanceof B 看A对象的原型链上 有没有 B的原型,返回bool(B是构造函数)
this
1、函数预编译过程中this–>window;
2、全局作用域里this–>window;
3、call/apply可以改变this指向
4、obj.func();func()里面的this指向obj
argument
argument.callee返回自身引用,argument.length
九、数组
定义数组方式:
var arr=[];var arr=new Array();
数组常用的方法
改变原数组
push,pop,shift,unshift,sort,reverse,splice
push,添加数据,返回数组长度
pop,把数组的最后一位剪切,返回数组最后一位
shift/unshift,unshift在数组前加数据,shift在数组前删数据
sort,ASCII码升序
自定义排序规则 原理:冒泡排序
reverse,逆转数据
splice,arr.splice(从第几位开始,截取多少的长度,在切口处添加数据)
不改变原数组
concat,join
concat,拼接数组
toString
slice(从该位开始截取,截取到该位)
join(字符串) arr1字符串arr2字符串arr3 string.split(字符串);
forEach
forEach是 ES5 中操作数组的一种方法,主要功能是遍历数组,其实说穿了,就是 for 循环的加强版,该语句需要一个回调函数,作为参数。回调函数的形参,依次为,value:遍历的数组内容;index:对应的数组索引,array:数组本身。**
arr.forEach(function(value,index,array){ console.log(value); console.log(index); console.log(array); })
类数组
类数组的特性:
属性要为索引(数字)属性,必须要有length属性,最好再加上push;
var obj={ "0":'a'; "1":'b'; "2":'c'; "length":3, "push":Array.prototype.push, "splice":Array.prototype.splice}
类数组本质是对象
优点:将数组和对象的特点集在一起
缺点:数组的一些方法需要自己添加
十、try…catch
在try里面的发生错误,不会执行错误后的try里面的代码
try{}catch(e) { //error error.message error.name console.log(e.name+":"+e.message);}
error.name的错误信息一共六种:
1、EvalError:eval()的使用与定义不一致2、RangeError:数值越界3、ReferenceError:非法或不能识别的引用数值4、SyntaxError:发生语法解析错误5、TypeError:操作数类型错误6、URIError:URI处理函数使用不当
ES5标准模式:
浏览器基于es3+es5的新增方法
es5严格模式:es3和es5冲突部分用es5,否则用es3
es5.0严格模式启动:写在逻辑的最顶端"use strict";
就是一行字符串,不会对不兼容严格模式的浏览器产生影响。
es5严格模式不支持方法:with,arguments.callee,func.caller
with:改变作用域链,将参数对象放到作用域链的最顶端。可用于代码简化
es5严格模式
变量赋值前必须声明
局部this必须被赋值
拒绝重复属性和声明
十一、DOM
DOM–>Document Object Model,是对HTML以及XML的标准编程接口。
DOM基本操作
对节点的增删查改
查://DOM、BOM系统自动生成的一组数据都是类数组形式
document代表整个文档
doucument.getElementById(’’);
doucument.getElementsByTagName(’’)[];
doucument.getElementsByName(’’)[];//不常用
doucument.getElementsByClassName(’’)[];//不常用,因为ie8及以下不兼容
.querySelector();//css选择器(‘div>span strong.demo’) 非实时的
querySelectAll();
遍历节点树 DOM对象的属性
parentNode:父节点,
childNodes:所有子节点,
firstChild,lastChild,
nextSibling:下一个兄弟节点 previousSibing:上一个兄弟节点
所有节点类型:
元素节点——1
属性节点——2
文本节点——3
注释节点——8
document——9
基于元素节点树的遍历
parentElement
children,返回当前元素子节点
firstElementChild,lastElementChild
nextElementSibling/previousElementSibling
节点的四个属性
nodeName
nodeValue,只有文本节点和注释节点有,值为文本内容,其他节点为null
nodeType,该节点的类型,只读
attributes,该节点的属性集合
节点的一个方法 Node.hasChildNodes();返回Boolean
DOM继承树
原型链:document–>HTMLDocument.prototype–>Document.prototype
getElementById定义在Document.prototype上
getElementByName定义在HTMLDocument.prototype上
getElementByTagName定义在Document.prototype和Element.prototype上
document.body/head/documentElement分别指body,head,HTML
增:
- document.createElement();
- document.createTextNode();
- document.createComment();
- document.createDocumentFragement();
插:
- RENTNODE.appendChild(); //剪切操作
- PARENTNODE.insetBefore(a,b);
删:
- parent.removeChild();
- child.remove();
替换:
- parent.replaceChild(new,origin);
Element节点的一些属性
- innerHTML
- innerText
Element节点的一些方法
- ele.setAttribute()
- eg:div.setAttribute(‘class’,‘demo’);
- ele.getAttribute()
十二、date对象,定时器,Global,获取窗口属性,脚本化CSS
Date:日期对象
-
创建
-
var date = new Date();
-
-
方法
- toLocaleString():返回当前date对象对应的时间本地字符串格式
- getTime():获取毫秒值。返回当前时间到1970.01.01零点的毫秒值
- setInterval
- clearInterval
- setTimeout
- 只执行一次
eg:
var i = 0;var timer = setInterval(function () { console.log(i++); if (i > 10) { clearInterval(timer); }}, 1000)
Global
url编码:在数据传输中,将字符转为Unicode编码,每个字符通过%分隔开
encodeURI(); url编码decodeURI(); url解码
eval():将js的字符串转为js代码执行
窗口尺寸
-
window.pageXOffsetwindow.pageYOffset
可视区窗口的尺寸
window.innerWidthwindow.innerHeight
查看元素的几何尺寸
domEle.offsetWidth;domEle.offsetHeight; 注意:不包含margin
查看元素的位置
domEle.offsetLeft;domEle.offsetTop; 对于无定位父级的元素,返回相对文档的坐标;对于有定位父级的元素,返回相对于最近的有定位的父级的坐标
让滚动条移动
三个方法:
scroll(),scrollTo() scrollBy()区别:scrollBy会在之前的位置上累加
脚本化CSS
读写元素CSS属性
dom.style.prop
- 可读写行间样式,没有兼容性问题,碰到float这样的保留字属性,前面应加css
- eg:float --> cssFloat
- 复合属性必须拆解,组合单词变成小驼峰式写法
- 写入的值必须是字符串格式
查询计算样式
- window.getComputedStyle(ele,null).prop
- 计算样式只读
- 返回的计算样式的值都是绝对值,没有相对单位
十三、事件
事件——交互体验的核心功能
绑定事件处理函数
-
elem.onXxx = function (event) {} 基本等同于写在HTML行间上
-
obj.addEventListener(type,fn,false);eg: div.addEventListener("click", function () { console.log("a"); }, false)注:可以为一个事件绑定多个处理程序
解除绑定事件:
-
elem.onclick = null;
-
elem.removeEventListener(type,fn,false);注:若绑定匿名函数,则无法解除
事件模型
事件冒泡
- 结构上(非视觉上)嵌套关系的元素,会存在事件冒泡,自子元素冒泡到父元素(自底向上)
事件捕获
- 结构上(非视觉上)嵌套关系的元素,会存在事件捕获,自父元素捕获至子元素(事件源元素)(自顶向下)
- 捕获:将addEventListener中的fn中false改为true
触发顺序:
- 先捕获,再执行,再冒泡
focus,blur,change,submit,reset,select等事件不冒泡
取消冒泡
- event.stopPropagation();
阻止默认事件
默认事件:表单提交,a标签跳转,右键菜单等
- return false:以对象属性的方式注册的事件才生效
常见的事件
-
点击事件
- onclick:单击事件
- ondbclick:双击事件
-
焦点事件
- onblur:失去焦点
- 一般用于表单校验
- onfocus:元素获得焦点
- onblur:失去焦点
-
加载事件
- onload:一张页面或一幅图像完成加载
-
鼠标事件
- click,mousedown,mousemove,mouseup,contextmenu,mouseover,mouseout,mouseenter,mouseleave
- mouseover,mouseout等同于mouseenter,mouseleave
- 用button来区分鼠标的按键,0/1/2
- click事件只能监听左键,只能通过mousedown和mouseup来判断鼠标键
- click,mousedown,mousemove,mouseup,contextmenu,mouseover,mouseout,mouseenter,mouseleave
-
键盘事件
- keydown,keyup,keypress
- keydown>keypress>keyup
- keydown和keypress的区别
- keydown可以响应任意键盘按键,keypress只可以相应字符类键盘按键
- keypress返回ASCII码,可以转换成相应字符.keydown对应的ASCII不准
-
选择和改变
- onchange:域的内容被改变
- onselect:文本被选中
-
表单事件
- onsubmit:表单被提交
鼠标事件
- click,mousedown,mousemove,mouseup,contextmenu,mouseover,mouseout,mouseenter,mouseleave
- 用button来区分鼠标的按键,0/1/2
- click事件只能监听左键,只能通过mousedown和mouseup来判断鼠标键
键盘事件
- keydown,keyup,keypress
- keydown>keypress>keyup
- keydown和keypress的区别
- keydown可以响应任意键盘按键,keypress只可以相应字符类键盘按键
- keypress返回ASCII码,可以转换成相应字符.keydown对应的ASCII不准
十四、JSON,异步加载,时间线,正则表达式
JSON
- JSON.parse(); string --> json
- JSON.stringify(); json --> string
异步加载js
JavaScript异步加载的三种方案:
- defer异步加载,但要等到dom文档全部解析完才会被执行。只有IE能用,也可以将代码写到内部。
- async异步加载,加载完就执行,async只能加载外部脚本,不能把js写在script标签里,执行时也不阻塞页面
- 创建script,插入到dom中,加载完毕后callback
正则表达式
两种创建方式:
-
直接量
-
var reg = /abc/im; i:ingoreCase g:global,全局匹配(查找所有匹配而非在找到第一个匹配后停止) m:multiline,执行多行匹配
-
-
new RegExp(“正则表达式”);
reg.test(),检测是否匹配
str.match(reg),返回匹配数组
十五、BOM
BOM:Browser Object Model 浏览器对象模型
BOM组成:
- Windows:窗口对象
- History:历史记录对象
- Location:地址栏对象
- Navigator:浏览器对象
- Screen:显示器屏幕对象
Windows对象:
创建:
- 不需要创建,直接使用window使用。 window.方法名();
- 可以省略window 方法名();
方法:
- 与弹出框有关的方法:
- alert()
- confirm() 显示带有一段消息以及确认按钮和取消按钮的对话框。返回Boolean
- prompt() 显示可提示用户输入的对话框。返回输入值
- 与打开关闭有关的方法
- close() 关闭浏览器窗口。 谁调用就关闭谁
- open() 打开一个新的浏览器窗口或查找一个已命名的窗口。
ES6新特性
let、const
let
- 块级作用域
- 同一作用域下,不能重复定义;不同作用域及父子作用域下,可以重复定义
- 没有域解析,不存在变量提升
const:和let特性一样
- const定义的变量不能修改,初始化时必须赋值
解构赋值
- 非常有用,特别是在做数据交互,ajax
eg:
let [a, b, c] = [12, [5, 6]];console.log(a, b, c);
注:左右两边,结构格式要保持一致
let json = { name: 'tom', age: 45, job: 'stu'};let {name, age, job:a} = json;console.log(name, age, a); //a相当于job的别名
解构的时候可以给默认值
let [a, b, c = "默认值"] = ['tom', 45];console.log(a, b, c);
字符串模板,字符串查找
字符串模板
语法:` ${变量} `;
let name = "tom";let age = 45;let str = `name=${name},age=${age}`;
字符串查找
- str.includes(),返回boolean
- str.startsWith(),字符串是否以谁开头
- str.endsWith()
箭头函数
语法
-
() = > 单个语句
-
() = > { ... return 返回值;}
注:
- 箭头函数中的this指当前函数所在的对象,而不是运行时所在的对象
- 箭头函数中没有arguments,用"…"
- 箭头函数不能作为构造函数
javascript:void(0)含义
eg:
<a href="javascript:void(0)">单击此处什么也不会发生</a>
当用户链接时,void(0) 计算为 0,但 Javascript 上没有任何效果。
href="#"与href="javascript:void(0)"的区别
# 包含了一个位置信息,默认的锚是**#top** 也就是网页的上端。
而javascript:void(0), 仅仅表示一个死链接。所以,该语句常用于超链接中,防止资源跳转
innerHTML和innerText的区别
在添加时,innerHTML,浏览器会将innerHTML中的标签解析出来,而innerText则会将会整个字符串内容作为文本内容
在打印时,两者没有区别
js动态获取项目虚拟路径
- sub():把字符串显示为下标。
- substr(start,length):在字符串中抽取从 start 下标开始的指定数目的字符。
- substring(start,stop):用于提取字符串中介于两个指定下标之间的字符。
function getContextPath() { let strPath = location.pathname; return strPath.substring(0, strPath.substr(1).indexOf('/') + 1);}
HTML解析顺序
dom树(HTML标签)和渲染树(css文件)同时生成,之后再将两个树合并,渲染
因为js中有对于dom元素的操作,为了避免冲突,所以js会阻塞dom树的生成。如果js可以不对dom元素进行操作,可以通过添加“defer”或“async”异步加载js(前端是单线程的,浏览器是多线程的)
Promise
1、回调函数
回调函数:被调用者回头调用调用者的函数,这种由调用方自己提供的函数叫回调函数。
eg:
在未来某个时刻,A函数t调用完成了,那么程序会回到它刚才离开的地方,并继续执行后半部分C函数。
2、什么是Promise?
Promise是异步编程的一种解决方案
- 从语法上讲,promise是一个对象,从它可以获取异步操作的消息;
- 从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。
promise有三种状态:pending(等待态),fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变。
创造promise实例后,它会立即执行。一般来说我们会碰到的回调嵌套都不会很多,一般就一到两级,但是某些情况下,回调嵌套很多时,代码就会非常繁琐,会给我们的编程带来很多的麻烦,这种情况俗称——回调地狱。这时候我们的promise 就应运而生、粉墨登场了。
3、Promise的基本使用
Promise是一个构造函数,自己身上有all、reject、resolve这几个眼熟的方法,原型上有then、catch等同样很眼熟的方法。
eg:
Promise的构造函数接收一个参数:函数,并且这个函数需要传入两个参数:
- Resolve:异步操作执行成功后的回调函数
- Reject:异步操作执行失败后的回调函数
then链式操作的用法
从表面上看,Promise只是能够简化层层回调的写法,而实质上Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,
eg:
catch的用法
我们知道Promise 对象除了then 方法,还有一个catch 方法,它是做什么用的呢?其实它和then 的第二个参数一样,用来指定reject 的回调。用法是这样:
效果和写在then 的第二个参数里面一样。不过它还有另外一个作用:在执行resolve 的回调(也就是上面then 中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch方法中。
前后端分离node的作用
“==”与"==="的区别
"==="是绝对相等
“==”的比较规则
- 先检查两个操作数的数据类型是否相同
- 如果相同,则比较两个数是否相等
- 如果不同,则先将两个数转换为相同数据类型,再进行比较
“===”的比较规则
- 先检查两个操作数的数据类型是否相同
- 若不同,直接返回false
- 若相同,则比较二者是否相等
跟==不同,当数据类型不同时, 不进行数据类型转换,直接返回false
null==undefined //truenull===undefined //falseNaN==NaN //falseNaN===NaN //false
类(class)
class Person { name; age; constructor(name, age) { this.name = name; this._age = age; } static method1() { console.log('这是一个静态方法'); } method2() { console.log('这是一个类方法'); } getName() { return this.name; } setName(name) { this.name = name; } getAge(){ return this.age; } setAge(age){ this.age=age; }}