js基础总结
数据类型部分
1. JavaScript有哪些数据类型,它们的区别?
基本数据类型:String、Number、Null、Undefined、Boolean、Symbol、BigInt
引用数据类型:Object(对象、数组、函数)
区别是存储位置不同,基本数据类型存储在栈中、引用数据类型存储在堆中
2. 数据类型检测方式有哪些?
typeOf:检测除null和引用类型
instanceOf:检测引用类型
Object.prototype.toString.call() :都能检测出
3. 判断数组的方式有哪些?
Object.prototype.toString.call(myArray) --- "[object, Array]"
myArray.__proto__ === Array.prototype ---- true
myArray instanceof Array ---- true
Array.isArray(myArray) ---- 通过es6的方法判断
Array.prototype.isPrototypeOf(myArray) ---- true
4. intanceof 操作符的实现原理及实现
left intanceof right:比较左边的_proto_和右边构造函数的prototype对象
实现:
1 function myInstanceof(left, right) { 2 3 let proto = Object.getPrototypeOf(left) 4 5 let prototype = right.prototype 6 7 while(true) { 8 9 if (!proto) return false 10 11 if (proto === prototype) return true 12 13 // 找不到继续向上遍历 14 15 proto = Object.getPrototypeOf(proto) 16 17 } 18 19 }
5. 为什么0.1 + 0.2 !== 0.3
因为js的运算操作都是先转换为2进制然后进行计算的,如果运算的数二进制为无限循环数,则相加必然不等于某个值
可以通过将0.1和0.2分别乘以100然后总体再除以100解决,toFixed会导致数据精度问题
6. == 强制类型转换规则
类型相同比较大小、判断是null和undefined直接返回true、类型不同先转类型
字符串和数字:字符串转为数字相比
boolean和any:boolean转number继续判断类型
Object和(String、Number、Symbol):把Object转为原始数据类型比较
js基础部分
1. DOM和BOM区别?
javascripct分为三大部分:ECMAScripct、DOM、BOM。
①、DOM(文档模型)是W3C标准,是html和xml应用程序的接口(API)
②、BOM是浏览器厂商根据DOM在各自浏览器上的实现。
③、window是BOM对象,而非js对象
区别就是DOM提供的是处理网页文档内容的方法和接口,而BOM提供的是处理浏览器窗口的方法和接口。
详解:https://www.cnblogs.com/wangxiang9528/p/9855358.html
备注:我们通常可以通过window.document来访问文档对象,document是DOM对象的根节点,所以可以说BOM包含了DOM。
原型
js万物皆可对象,对象都有原型(除了Null和Undefined),我的理解是原型就是对象上的默认属性和方法。
①、比如Object、Function、Array、String、Number的原型prototype就是一个对象存储了这些对象各自的属性和方法(比如toString)。
备注:Object原型是对象,存储了对象的一些属性和方法(toString、isPrototypeOf、hasOwnPrototype、valueOf),Array原型Array.prototype就有它自己的方法push和pop,String和Number等同理。
②、new Object()或者new XXX()就是新创建了一个相对应的对象,然后继承了该对象原本的属性和方法也就是原型,就是新建的对象指向了原型对象,属性名为_proto_,而值为原型对象的prototype。
③、自定义的方法,例如function myfun() {},不设置它的原型就是Object.prototype
原型链
对象的原型是一个对象,这个对象又可能是另外一个对象的原型,这个链式结构就叫做原型链。
例如:function foo() {} 形成的原型链: foo ---> Function.prototype ---> Object.prototype ---> null
prototype和_proto_区别
每个对象都有一个_proto_对象指向构建它的原型对象。
函数比较特殊,函数都有一个显式prototype和隐式_proto_的两个原型对象。
其他引用对象都有一个隐式的原型对象_proto_
作用域、作用域链
①、作用域是什么?
我的理解js中的作用域就是代码执行的范围,就是说一个变量、函数申明后可访问的区间。
es6之前js的作用域只有全局作用域和函数作用域,es6引入了const、let之后使代码有了块级作用域,在一定程度上解决了变量提升造成代码混乱等一些问题。
②、 作用域链概念?
作用域链的就是在js调用栈中,每个执行上下文都有一个指向外部的outer,在查找变量时首先从自己的执行上下文中查找,查不到再去outer指向的作用域中查找,查找所经过的路径连接就是作用域链。
补充:疑问就是outer是如何指向正确的上下文的呢?其实是由词法作用域来确定的,在代码编译阶段根据代码所在函数声明的位置来决定的,所以此法作用域就能预测执行的代码如何查找以及查找路径。如下图:
闭包
在js中,内部函数(inner)始终能够访问外部函数(outer)的变量,当通过调用外部函数返回一个内部函数inner之后,即使当外部函数执行完毕被销毁,返回的内部函数还依然存在在内存中,然而内部函数用到的外部函数的变量的集合就叫做外部函数的闭包。只有通过调用内部函数才能访问到,即类似于内部函数到哪里都背着这个专属背包,所以被称为闭包。
如下:外部函数foo返回了一个内部函数inner,inner带着外部函数的变量test1、myName提供给外部访问,他们就是foo的闭包。