一、数据类型有哪些以及区别
1.八种数据类型
- 原始数据类型:1.number;2.string;3.boolean;4.null;5.undefine;6.symbol
- 引用数据类型:1.object;2.array;3.function
2.区别
- 存储位置:原始数据类型储存在栈中;引用数据类型实际数据储存在堆中,地址储存在栈中
- 赋值方式:原始数据类型赋值时,会将值赋值给新变量;引用数据类型赋值时,只将地址赋值给新变量
- 比较方式:原始数据类型比较值是否相等;引用数据类型比较地址是否相等,即是否指向同一个对象
3.symbol特点
- 创建:通过Symbol()函数创建
- 唯一性:每个通过symbol()函数创建出的值都是唯一的,即使传入的参数相同,也不会创建出相同symbol
- 不可变:一旦创建,不能被修改
- 不能与其他类型进行运算
二、数据类型检测方法
- typeof + data:用于检测原始数据类型,但object array null会被检测为object
- data + instanceof + type:只能正确判断引用数据类型
- object.prototype.toString.call()
- constructor
三、判断数组的方法有哪些
- Array.isArray
- instanceof
- 原型.tostring.call()
四、简述js中的this
this是执行上下文中的一个属性,它指向最后一次调用函数方法的对象,在实际开发中,this指向可以用四钟调用模式来判断
- 作为普通函数调用:直接作为函数被调用,指向window
- 作为对象方法调用:指向该对象
- 构造函数调用:指向新创建的对象。如果一个函数用 new 调用时,函数执行前会新创建一个对象
- 使用call、apply、或bind方法:使用这三个方法可以手动设置this的值。call和apply直接调用函数设置this,区别在于参数传递方式;call:第一个参数指定this指向,其余参数用逗号分隔依次传递;apply:第一个参数同call,其余参数放在数组中作为第二个参数传递。bind时返回一个新函数,新函数的'this'被固定
- 箭头函数:没有自己的this,继承自外层作用域
五、箭头函数和普通函数的区别
- 更简洁
- 没有自己的this
- 继承来的this指向不会被改变,call、apply、bind也不能改变
- 不能作为构造函数使用:因为没有自己的this指向,且不能改变,而用new创建函数时,会改变this指向
- 没有自己的arguments:arguments->是一个在函数内部自动可用的对象,它包含了调用该函数时传入的所有参数。
- 没有prototype
- 不能用作Generator函数,不能使用yield关键字
六、let const var的区别
- 块级作用域:let、const有块级作用域;var没有。作用:防止内层变量覆盖外部变量
- 变量提升:var存在变量提升;let、const没有,只能先声明后使用
- 暂时性死区:let、const有暂时性死区(在未声明变量之前,该变量都是不可用的);var没有
- 初始值设置:let、var可以不用设置初始值,const必须设置
- 重复声明变量:var可重复,后面会覆盖前面的;let、const不可重复
- 重新赋值:let和var可以重新赋值;const不可以重新赋值
七、new操作符执行过程
- 创建一个空对象
- 设置原型:将构造函数的原型赋值给空对象的原型
- 让函数的this指向该对象,执行构造函数
- 返回对象,如果返回是值类型则返回新对象;如果返回是引用类型则返回引用类型的对象而非新创建的对象
八、数组有哪些原生方法
- 数组字符串转换:join,split
- 删除或新增:push尾部+,pop尾部-;unshift首部+,shift首部-
- 连接两个数组:concat,返回新数组,不影响原数组
- 重排方法:sort、reverse
- 截取数组/字符串:slice( [开始索引,结束索引) ) ]
- 删除、插入、替换元素:splice,三个参数,1.插入位置的索引;2.删除元素个数,为0则不删除;3.用于替换的元素。参数2不为0且参数3存在->替换;参数2为不为0,且无参数3->删除,参数2为0,且参数3存在->插入
- 索引查找:IndexOf、lastIndexOf
- 迭代方法:map、forEach、every、some、filter
- reduce/reduceRight:用于求和、求乘积、最大值最小值、数组去重等
九、数组去重的方法
- reduce
- 利用set数据结构:set数据结构中元素唯一性自动取宠,再用Array.from或扩展运算符,将set转换回数组
- 双重循环遍历
- filter
十、数组的遍历方法
- forEach
- map
- for...of
- filter
- every/some
- find/findeIndex
- reduce/reduceRight
十一、map和forEach的qubie
- map会返回一个新数组,不会改变原数组的值
- forEach没有返回值,对数组数据进行操作会改变原数组的值
十二、for...in 和 for...of的区别
- for...in用于遍历对象的可枚举属性
- for...of用于遍历可迭代对象如数组、字符串、Set、Map等,直接访问可迭代对象的值
十三、ES6中新的数据结构
- Set:是一种集合数据结构,类似于数组,但成员具有唯一性,不会包含重复的值。add:添加元素;has判断元素是否存在;delete删除元素;size获取元素个数。
- Map:是一种键值对的数据结构,类似于对象,但Map的键可以是任何类型,而对象的键只能是字符串或Symbol类型。set:设置键值对;get:获取键值对;has:判断键是否存在;delete:删除键值对;size:获取键值对数量。
十四、原型和原型链
1、对原型和原型链的理解
原型是js对象的一个特性,它就像是一个基础模板,新对象可以从中继承属性和方法。每个对象都有一个隐式原型链接,指向它的原型对象。多个原型对象层层嵌套,就形成了原型链。当我们访问对象的一个属性时,吐过这个对象没有,就会沿着原型链向上查找,直到找到或者到达原型链顶端。
2.原型链指向
每个构造函数都有一个prototype属性,指向它的原型对象。构造函数实力的_proto_属性会指向构造函数的prototype属性所指向的原型对象。
3.原型链的终点是什么?->null
因为所有对象最终都继承自Object.prototype,而Object.prototype的_proto_的值为null,表示原型链到此结束。
4.判断属性是否属与原型链的属性
hasOwnProperty()
十五、闭包、作用域(链)、执行上下文
1.闭包:
定义:函数嵌套,且内部函数引用外部函数变量。 优点:通过闭包可以将变量隐藏在内部函数中,实现数据的封装和保护 缺点:可能会造成内存泄漏
2.作用域(链):
全局作用域: 函数作用域: 块级作用域:let、const可以声明具有块级作用域的变量 作用域链:在当前作用域中查找变量,若找不到,就依次向父级作用域寻找,直到找到window被终止,这个过程为作用域链
3.执行上下文类型:
全局执行上下文:任何不在函数内部的都是全局执行上下文,首先会创建一个全局的window对象,this指向window,一个程序中只有一个全局执行上下文。 函数执行上下文:当一个函数被调用时,就会为该函数创建一个新的执行上下文,函数的上下文可以有任意多个。 eval函数上下文:
4.执行上下文栈->执行过程 (后进后出)
js引擎使用执行上下文栈来管理执行上下文 当js执行代码时,首先遇到全局代码,创建一个全局上下文并压入执行栈中,每当遇到一个函数调用,就会为该函数创建一个新的执行上下文,并压入栈顶,引擎会执行位于执行上下文栈顶的函数,当函数执行完后从栈中弹出,再执行下一个执行上下文,当所有代码都执行完毕后,从栈中弹出全局执行上下文。
5.执行上下文概述
在执行一点js代码之前,需要先进行代码解析,解析的时候会创建一个全局上下文环境,先把代码中即将执行的变量、函数声明都拿出来,变量赋值为undefined,函数声明好可使用,再开始正式执行程序。函数也一样。
十六、异步编程的实现方式
1.Promise:
- 定义:是js中用于处理异步操作的一种机制,它代表了一个异步操作的最终完成或失败及其结果值。它能让异步代码更易于阅读、书写和维护,避免传统回调函数导致的“回调地狱”问题
- 状态:三种状态:进行中,已成功,已失败,初始状态为进行中,一旦状态改变就不会再变
- 基本用法:通过new创建promise实例,异步操作成功时调用resolve函数,失败时调用reject函数。使用then方法处理Promise成功或失败的结果,catch方法用于捕获Promise被拒绝的情况。
- 链式调用:then方法返回一个新的Promise,可以进行链式调用,方便对异步操作的结果进行连续处理
- 组合多个Promise:promise.all->将多个Promise包装成一个新的Promise,只有当所有传入的Promise都成功时,新的Promise才会成功,结果是一个包含所有成功值的数组;Promise.race->也会将多个Promise包装成一个新的Promise,但是要有一个Promise率先改变状态,新的Promise就会跟着改变状态返回该Promise结果
2.async/await:基于Promise的异步操作关键字
- async:用于定义异步函数,返回一个Promise对象。
- await:只能在async函数内部使用,当await一个Promise时,async函数的执行会暂停,指导Promise有了记过,再继续执行await后面的代码,如果Promise失败,会抛出异常,可以使用try...catch捕获
- 优势:避免了过多的then和catch链式调用。
十七、ES6新特性
- 新的变量声明方式:let、const
- 箭头函数
- 模板字符串
- 解构赋值
- 扩展运算符
- symbol数据类型
- set、map数据结构
- 新增模块化:import导入、export导出
- 引入for...of循环
- Promise
- Proxy:允许在对象和函数调用等操作前后添加自定义的行为,接收两个参数:第一个是要被代理的对象,第二个是处理器对象,包含多种拦截器。