js数据类型
基本数据类型
ES5:undefined, boolean, number, string
ES6: symbol
引用数据类型
object; 包含Object, Array, function。
备注:null是引用类型,指向的引用地址是空。所以识别的时候是object
数据类型存储
基本数据类型直接存储在栈内存中
引用数据类型存储在栈内存与堆内存中,变量名存在栈中,值存在堆中。栈中存的是引用地址,所以引用地址是不变的,但是引用地址里的内容是可以改变的。
数据类型的判断
typeof (1)只能识别基本数据类型 (2)识别函数 (3)判断是否是引用类型(但不能判断是数组还是对象)
instanceof 判断引用类型,方法: obj instanceof Array;判断变量属于哪个class或构造函数
Object.prototype.toString.call() 判断引用数据类型
数组的遍历
for循环
forEach():没有返回值,只是针对每个元素调用func的结果。不支持break和continue,所以在循环中无法跳出循环
map(): 返回新的Array,每个元素为调用func的结果
filter(): 返回符合func条件的元素数组
some(): 返回boolean, 判断是否有元素是否符合func条件(只要有一个符合即可)
every(): 返回boolean, 判断每个元素是否都符合func条件
reduce(): 接受一个函数作为累加器
es6新增
find(): 返回第一个符合条件的元素
findIndex(): 返回的值为符合条件第一个元素的索引
for of
箭头函数
箭头函数中没有this,继承外面一层的this
不可以当作构造函数
不可以使用arguments对象,可以用es6中的...args(rest运算符)代替argument
深拷贝和浅拷贝
浅拷贝
Object.assigin 对于引用数据类型,拷贝的是只是引用地址,不是内容
深拷贝
JSON.parse(JSON.stringify()) 不支持对于function的深拷贝,支持对象、数组、基本数据类型
递归
面向过程 与 面向对象
把大象装进冰箱一共分几步?
1、打开冰箱
2、把大象装进去
3、关上冰箱门
以上属于面向过程,关心整个过程的步骤。
面向对象:分析当前需求中有哪些对象,对象具有哪些属性、方法和行为。什么叫属性,比如说我的名字叫仙女,我18岁就是我的属性,那我有什么方法呢,我会吃饭,会敲代码就是我的方法或者我的行为。
上图中对象包括大象和冰箱
大象的属性:体积(能不能塞的进冰箱),进冰箱的方法未知
冰箱的属性: 体积(能不能装大象),装大象的方法未知,因为冰箱没有手哈哈
大象怎么进冰箱呢,冰箱怎么让大象进去呢? ---隐藏对象
以上是面向对象的分析方式
js是一种基本对象的语言。
类与对象
人 仙女
类(class)是对象(object)的模板,定义了一组对象共有的属性和方法。
es5中的类与继承
原型举例:做月饼的时候需要做100个带花纹的月饼,有两种实现方式,一种是把月饼做好,再一个一个的雕刻花纹,一种是做一个带有花纹的模具,做月饼的时候就用模具做,让月饼天生自带花纹,这种就是原型
继承
es6中的类与继承
原型与原型链
js 本身是基于原型继承的语言
每个函数都有显式原型prototype
每个实例都有隐式原型__proto__
实例的隐式原型__proto__指向对应的构造函数的显式原型Prototype
作用域和闭包
作用域
全局作用域
函数作用域
块级作用域
自由变量
一个变量在当前作用域没有定义,但是被是用了
向上级作用域一层一层依次寻找,直到找到为止
如果到全局作用域都没找到,则报错xx is not defined
闭包
闭包是作用域应用的特殊情况,有两种表现:
(1)函数作为参数被传递
(2)函数作为返回值被返回
所有的自由变量的查找,是在函数定义的地方,向上级作用域查找,不是在执行的地方!!!
实际开发中闭包的应用
闭包的特点:有一个外部函数和一个内部函数,内部函数会调用外部函数的变量, 保证外部函数的变量的状态不被释放。
下面引申一道面试题
在for循环中执行setTimeOut,结果是什么?
为什么是3个3呢?
因为setTimeOut是异步任务,for循环是同步任务,在setTimeOut执行时,for循环已经执行完毕
怎么顺序输出1,2,3呢?
方案一:使用闭包
方案二:把Var改成let
原因是在转换成es5语法后,自动的形成了闭包。
this
this取什么值是在函数执行的时候确定的,不是在函数定义的时候确定的
箭头函数中没有this,箭头函数中的this是取它上级作用域的this
this的应用场景
当做普通函数被调用 => window
是用call apply bind => 传入什么绑定什么
作为对象方法使用 => 返回对象本身
在calss的方法中调用 => 实例本身
箭头函数 => 找上级作用域的this
异步
JS是单线程的。只能同时做一件事。
同步任务与异步任务
js要前一个任务执行完之后再执行下一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。由于不能一直卡着等待,就有了异步。于是,所有任务可以分成两种,一种是同步任务,另一种是异步任务。
Ajax的原理
promise
优雅的解决异步回调地狱
Promise.all()只要有一个失败,就会进入catch,拿不到其余成功的结果,要数组中所有promise对象完成才算成功
Promise.race()只要有一个成功就算成功
Promise.allSettled() 其中有失败不影响数组中别的任务结果
event loop(事件循环/事件轮询)
js是单线程运行的,异步要基于回调来实现,event loop就是异步回调的实现原理
for...in(以及forEach for)是常规的同步遍历
for...of常用于异步遍历
宏任务和微任务
宏任务:setTimeOut, setInterval, Ajax, DOM事件
微任务:Promise async/await
微任务执行时机比宏任务要早