1、JavaScript
1.1、基本数据类型(7种)
1、number
js不区分小数和整数
123//整数
123.1 //浮点数
1.123e3 //科学计数法
-9 //负数
NaN //Not a number isNaN()判断是否为NaN
Infinity //表示无限大
2、字符串
‘abc’ “abc”
3、布尔值
true,false
4、null和undefined
- null 空
- undefined 未定义
5、数组
一系列相同类型的对象
var arr = [1,2,3,4,'string',true];
new Array(1,2,4,5,'hello');
去数组下标:如果越界就会undefined
6、对象
对象是大括号,数组是中括号
var person = {
name: "zhouyi",
age: 4,
tags: ['js','java','web','...']
}
取对象的值
person.age
> 4
person.name
> 'zhouyi'
person.tags
> (4) ['js', 'java', 'web', '...']
1.2、this的指向(new,隐式绑定,显式绑定)
this默认绑定我们可以理解为函数调用时无任何调用前缀的情景,它无法应对我们后面要介绍的另外四种情况,所以称之为默认绑定,默认绑定时this
指向全局对象(非严格模式)
默认绑定:这条规则是最常见的,也是默认的。当函数被单独定义和调用的时候,应用的规则就是绑定全局变量window(严格模式下是undefined)。即没有其他绑定规则存在时的默认规则
NEW绑定准确来说,js中的构造函数只是使用``new
调用的普通函数,它并不是一个类,最终返回的对象也不是一个实例,只是为了便于理解习惯这么说罢了。
1.以构造器的prototype属性为原型,创建新对象;
2.将this
(可以理解为上句创建的新对象)和调用参数传给构造器,执行;
3.如果构造器没有手动返回对象,则返回第一步创建的对象
隐式绑定,如果函数调用时,前面存在调用它的对象,那么this
就会隐式绑定到这个对象上。如果函数调用前存在多个对象,this
指向距离调用自己最近的对象
显式绑定是指我们通过call、apply以及bind方法改变this
的行为,相比隐式绑定,我们能清楚的感知 ``this
指向变化过程。
1.3、Function的call, apply, bind方法
call
调用一个对象的一个方法,以另一个对象替换当前对象。
function Animal(name){
this.name=name;
this.showName=function(){
console.log(this.name);
}
}
function Dog(name){
Animal.call(this.name);
}
var dog=new Dog("Crazy dog");
dog.showName();
输出:Crazy dog
Animal.call(this) 的意思就是使用 Animal对象代替this对象,那么Dog就能直接调用Animal的所有属性和方法。
apply
应用某一对象的一个方法,用另一个对象替换当前对象。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vSBfWjVg-1657884268102)(file://C:\Users\chow\AppData\Roaming\Typora\typora-user-images\image-20211213152034290.png?lastModify=1639723017)]
bind
bind()
方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()
方法的第一个参数作为 this
,传入 bind()
方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。
注意:bind
方法的返回值是函数
总结
- apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
- apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
- apply 、 call 、bind 三者都可以利用后续参数传参;
- bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。
1.4、Promise, eventloop(事件循环),宏任务和微任务
JS引擎常驻于内存中,等待宿主将JS代码或函数传递给它。
也就是等待宿主环境分配宏观任务,反复等待 - 执行即为事件循环。
1、执行栈选择最先进入队列的宏任务(一般都是script),执行其同步代码直至结束;
2、检查是否存在微任务,有则会执行至微任务队列为空;
3、如果宿主为浏览器,可能会渲染页面;
4、开始下一轮tick,执行宏任务中的异步代码(setTimeout等回调)
遇到宏任务先执行宏任务,再看eventQueue里面有没有微任务,执行
1.5、闭包(概念,用途,手写)
闭包的作用:隐藏变量,避免全局污染;可以读取函数内部的变量。
闭包的概念: 有一个A函数,在A函数内部返回一个B函数;在A函数外部有变量引用这个B函数;B函数内部访问着A函数内部的私有变量。(核心就是利用执行空间不销毁的原理)、
for(var i=0;i<10;i++){
~function(){
setTimeout(()=>{
console.log(i);//10次10 获得执行次数
},1000)
}(i);
}
for(let i=0;i<10;i++){
~function(){
setTimeout(()=>{
console.log(i);//0~9 获得每一个i
},1000)
}(i);
}
1.6、原型链
__ proto __:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iF0sEHyg-1657884268103)(file://C:\Users\chow\AppData\Roaming\Typora\typora-user-images\image-20211213161448887.png?lastModify=1639724451)]
1.7、继承(extends,原型链继承,构造函数继承,组合继承,寄生组合继承)
原型链继承
重点:让新实例的原型等于父类的实例。
特点:1、实例可继承的属性有:实例的构造函数的属性,父类构造函数属性,父类原型的属性。(新实例不会继承父类实例的属性!)、
缺点:1、新实例无法向父类构造函数传参。
2、继承单一。
3、所有新实例都会共享父类实例的属性。(原型上的属性是共享的,一个实例修改了原型属性,另一个实例的原型属性也会被修改!)
本质:查看对象原型
构造函数继承
重点:用.call()和.apply()将父类构造函数引入子类函数(在子类函数中做了父类函数的自执行(复制))
特点:1、只继承了父类构造函数的属性,没有继承父类原型的属性。
2、解决了原型链继承缺点1、2、3。
3、可以继承多个构造函数属性(call多个)。
4、在子实例中可向父实例传参。
缺点:1、只能继承父类构造函数的属性。
2、无法实现构造函数的复用。(每次用每次都要重新调用)
3、每个新实例都有父类构造函数的副本,臃肿。
组合继承**:组合原型链和构造函数
重点:结合了两种模式的优点,传参和复用
特点:1、可以继承父类原型上的属性,可以传参,可复用。
2、每个新实例引入的构造函数属性是私有的。
缺点:调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数。
寄生组合继承
寄生组合式继承(常用)
寄生:在函数内返回对象然后调用
组合:1、函数的原型等于另一个实例。2、在函数中用apply或者call引入另一个构造函数,可传参
1.8、深拷贝和浅拷贝
深拷贝浅拷贝只针对对象和数组这种引用数据类型。
浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
1.9、事件冒泡/捕获,事件委托,阻止冒泡,哪些事件不能冒泡
1、一个完整的JS事件流是从window开始,最后回到window的一个过程
2、事件流被分为三个阶段(15)捕获过程、(56)目标过程、(6~10)冒泡过程
取消冒泡:
标准的W3C 方式:e.stopPropagation();这里的stopPropagation是标准的事件对象的一个方法,调用即可
非标准的IE方式:ev.cancelBubble=true; 这里的cancelBubble是 IE事件对象的属性,设为true就可以了
事件委托:
把事件交给父级处理。
window.