JavaScript

62 阅读9分钟

一、数据类型有哪些以及区别

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
  • 不可变:一旦创建,不能被修改
  • 不能与其他类型进行运算

二、数据类型检测方法

  1. typeof + data:用于检测原始数据类型,但object array null会被检测为object
  2. data + instanceof + type:只能正确判断引用数据类型
  3. object.prototype.toString.call()
  4. constructor

三、判断数组的方法有哪些

  1. Array.isArray
  2. instanceof
  3. 原型.tostring.call()

四、简述js中的this

this是执行上下文中的一个属性,它指向最后一次调用函数方法的对象,在实际开发中,this指向可以用四钟调用模式来判断

  1. 作为普通函数调用:直接作为函数被调用,指向window
  2. 作为对象方法调用:指向该对象
  3. 构造函数调用:指向新创建的对象。如果一个函数用 new 调用时,函数执行前会新创建一个对象
  4. 使用call、apply、或bind方法:使用这三个方法可以手动设置this的值。call和apply直接调用函数设置this,区别在于参数传递方式;call:第一个参数指定this指向,其余参数用逗号分隔依次传递;apply:第一个参数同call,其余参数放在数组中作为第二个参数传递。bind时返回一个新函数,新函数的'this'被固定
  5. 箭头函数:没有自己的this,继承自外层作用域

五、箭头函数和普通函数的区别

  1. 更简洁
  2. 没有自己的this
  3. 继承来的this指向不会被改变,call、apply、bind也不能改变
  4. 不能作为构造函数使用:因为没有自己的this指向,且不能改变,而用new创建函数时,会改变this指向
  5. 没有自己的arguments:arguments->是一个在函数内部自动可用的对象,它包含了调用该函数时传入的所有参数。
  6. 没有prototype
  7. 不能用作Generator函数,不能使用yield关键字

六、let const var的区别

  1. 块级作用域:let、const有块级作用域;var没有。作用:防止内层变量覆盖外部变量
  2. 变量提升:var存在变量提升;let、const没有,只能先声明后使用
  3. 暂时性死区:let、const有暂时性死区(在未声明变量之前,该变量都是不可用的);var没有
  4. 初始值设置:let、var可以不用设置初始值,const必须设置
  5. 重复声明变量:var可重复,后面会覆盖前面的;let、const不可重复
  6. 重新赋值:let和var可以重新赋值;const不可以重新赋值

七、new操作符执行过程

  1. 创建一个空对象
  2. 设置原型:将构造函数的原型赋值给空对象的原型
  3. 让函数的this指向该对象,执行构造函数
  4. 返回对象,如果返回是值类型则返回新对象;如果返回是引用类型则返回引用类型的对象而非新创建的对象

八、数组有哪些原生方法

  1. 数组字符串转换:join,split
  2. 删除或新增:push尾部+,pop尾部-;unshift首部+,shift首部-
  3. 连接两个数组:concat,返回新数组,不影响原数组
  4. 重排方法:sort、reverse
  5. 截取数组/字符串:slice( [开始索引,结束索引) ) ]
  6. 删除、插入、替换元素:splice,三个参数,1.插入位置的索引;2.删除元素个数,为0则不删除;3.用于替换的元素。参数2不为0且参数3存在->替换;参数2为不为0,且无参数3->删除,参数2为0,且参数3存在->插入
  7. 索引查找:IndexOf、lastIndexOf
  8. 迭代方法:map、forEach、every、some、filter
  9. reduce/reduceRight:用于求和、求乘积、最大值最小值、数组去重等

九、数组去重的方法

  1. reduce
  2. 利用set数据结构:set数据结构中元素唯一性自动取宠,再用Array.from或扩展运算符,将set转换回数组
  3. 双重循环遍历
  4. filter

十、数组的遍历方法

  1. forEach
  2. map
  3. for...of
  4. filter
  5. every/some
  6. find/findeIndex
  7. 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,可以进行链式调用,方便对异步操作的结果进行连续处理
  • 组合多个Promisepromise.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:允许在对象和函数调用等操作前后添加自定义的行为,接收两个参数:第一个是要被代理的对象,第二个是处理器对象,包含多种拦截器。