1. 介绍一下JS的基本数据类型

  1. Number数字类型

  2. String字符串类型

  3. Boolean布尔类型

  4. Null 空对象

  5. Undefined

    Symbol

    bigint

引用类型

引用数据类型统称为 Object对象 主要包括 对象 数组 函数 日期 正则等 Array Date Function RegExp

2. script 标签中 defer 和 async 的区别?

  • script:会阻碍HTML解析,只有下载好并且执行完脚本才会继续解析HTML
  • async:解析HTML过程中尽心脚本的异步下载,下载成功马上执行,中间会阻断HTML
  • defer:完全不会阻碍HTML解析,解析完成再按顺序执行脚本

2. js变量和函数声明的提示

在js中变量和函数的声明 会提升到最顶部执行

  1. 函数的提升高于变量的提升
  2. 函数内部如果用var声明相同名称的外部变量,函数讲不会向上寻找
  3. 匿名函数不会提升

3. 闭包

我的理解:

在函数作用域内,内层函数可以访问到外层函数的变量 且return的是一个函数 构成闭包

好处:构成缓存可以封装私有属性或者私有方法

坏处:比较耗费内存,使用不当会造成内存泄漏

4. == 和 === 的区别

== 是非严格意义上的相等 值相等就相等

=== 是严格意义上的相等, 会比较两边的数据类型和值大小还有引用地址

5. this

  • 普通函数中的this指向window
  • 定时器中的this指向window
  • 箭头函数没有this,它的this指向取决于外部环境
  • 事件中的this指向事件的调用者
  • 如果有new关键词这this则指向new出实例对象

6. js中 数组 和 对象的遍历

for in for foreach for of

7, map 和 forEach 的区别

forEach 方法就是遍历与循环,默认有三个传参分别是数组的内容 item项 索引index 和当前数组arr 不会改变原数组

map方法用法和foreach 一致,但是不同的是它会返回一个新数组,所以需要有return 返回值 如果没有则返回undefined

7.1 请你说说 for…in 和 for…of 的区别

for…in 获取的是对象的键名 会遍历整个对象的原型链,性能差不推荐使用

for…of 遍历获取的是对象的键值 则不会遍历原型链

7.3 说一下 slice splice split 的区别?

slice,该方法是对数组进行部分截取 然后返回一个新数组 不改变原数组

splice 移除,若有两个参数,则返回一被删除的字符串,如果有额外的参数,则删除并替换这个新参 改变原数组

split 把字符串分割为数组

8.箭头函数 和 普通函数 有什么区别

箭头函数是匿名函数,不能作为构造函数,不能使用new

箭头函数不能绑定arguments,

this的作用域不同,箭头函数不能绑定this ,会捕获上下文的this值,作为自己的this值

8.1 普通函数和构造函数的区别

1.习惯构造函数也是一个普通函数,创建方式和普通函数一样 但是构造函数习惯大写

2.调用方式,普通函数直接调用,构造函数要用 new关键字调用

3.this指向不同,普通函数内部this指向调用函数的对象(如无则指向window) 构造函数this指向new出来的实例

4.返回值:构造函数默认返回的是创建的对象(实例)普通函数由 return 决定

5.构造函数的函数名与类名相同

9. JS 中常见的内存泄漏有哪些

1.意外的全局变量

2.被遗忘的计时器或者回调函数

3.脱离DOM的引用

4.闭包

9.同源策略

同源指的是: 域名 协议 端口号 相等

谈谈你平时都用哪些方法进行性能优化

  • 减少http请求次数
  • 打包压缩线上代码
  • 使用懒加载 雪碧图 cdn加载包

10. 如何解决跨域

jsonp 跨域

node.js 中间间代理跨域

11 严格模式的限制

变量必须先声明再使用 函数的参数不能有同名属性 不能使用with语句 禁止this指向全局对象

12. ES6 新增

新增模板字符串 箭头函数 for of promise对象 新增let 和 const 命名来声明变量 还有引入module 模块概念

13.什么是原型 原型链?

原型:函数有原型,函数上有个属性叫prototype,函数的这个原型指向一个对象 ,也就是原型对象 ,这个原型对象有一个constructor属性 指向函数本身

原型链:每一个实例对象上都有一个proto属性,指向构造函数的原型对象,构造函数的原型对象也是一个对象;也有一个proto属性,这样一层一层往上找到过程就形成原型链

14.对 JS 中 作用域的理解

作用域包括 全局作用域 函数作用域 块级作用域

  1. 全局作⽤域中创建的变量,在任意地⽅都可以访问
  2. 函数作⽤域中的变量,只有在函数内部才能访问
  3. 块级作⽤域中的变量,只能在当前块中进⾏访问

**15. Ajax请求 **

Ajax的原理简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用JavaScript来操作DOM而更新页面

实现的过程

请求:

创建 Ajax 核心对象 XMLHttpRequest

const xhr = new XMLHttpRequest();

通过 XMLHttpRequest 对象的 open() 方法与服务端建立连接

xhr.open(method, url, [async][, user][, password])

构建请求所需的数据内容,并通过XMLHttpRequest对象的 send() 方法发送给服务端

xhr.send([body])

响应:

通过 XMLHttpRequest 对象提供的 onreadystatechange 事件监听服务器端你的通信状态

接受并处理服务端向客户端响应的数据结果

将处理结果更新到 HTML页面中

const xhr = new XMLHttpRequest();
//响应
xhr.onreadystatechange = function(e){
if(xhr.readyState === 4){ //整个请求过程完毕
if(xhr.status >= 200 && xhr.status<=300){
console.log(xhr.responseText) //服务端返回的结果
}
}
}
//请求
xhr.open('POST','url')
xhr.send(data)

封装

//封装一个ajax请求
function ajax(options) {
//创建XMLHttpRequest对象
const xhr = new XMLHttpRequest()

//初始化参数的内容
options = options || {}
options.type = (options.type || 'GET').toUpperCase()
options.dataType = options.dataType || 'json'
const params = options.data

//发送请求
if (options.type === 'GET') {
xhr.open('GET', options.url + '?' + params, true)
xhr.send(null)
} else if (options.type === 'POST') {
xhr.open('POST', options.url, true)
xhr.send(params)

//接收请求
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
let status = xhr.status
if (status >= 200 && status < 300) {
options.success && options.success(xhr.responseText, xhr.responseXML)
} else {
options.fail && options.fail(status)
}
}
}
}

使用

ajax({
type: 'post',
dataType: 'json',
data: {},
url: 'https://xxxx',
success: function(text,xml){//请求成功后的回调函数
console.log(text)
},
fail: function(status){////请求失败后的回调函数
console.log(status)
}
})