1. 介绍一下JS的基本数据类型
Number数字类型
String字符串类型
Boolean布尔类型
Null 空对象
Undefined
Symbol
bigint
引用类型
引用数据类型统称为 Object对象 主要包括 对象 数组 函数 日期 正则等 Array Date Function RegExp
2. script 标签中 defer 和 async 的区别?
- script:会阻碍HTML解析,只有下载好并且执行完脚本才会继续解析HTML
- async:解析HTML过程中尽心脚本的异步下载,下载成功马上执行,中间会阻断HTML
- defer:完全不会阻碍HTML解析,解析完成再按顺序执行脚本
2. js变量和函数声明的提示
在js中变量和函数的声明 会提升到最顶部执行
- 函数的提升高于变量的提升
- 函数内部如果用var声明相同名称的外部变量,函数讲不会向上寻找
- 匿名函数不会提升
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 中 作用域的理解
作用域包括 全局作用域 函数作用域 块级作用域
- 全局作⽤域中创建的变量,在任意地⽅都可以访问
- 函数作⽤域中的变量,只有在函数内部才能访问
- 块级作⽤域中的变量,只能在当前块中进⾏访问
**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)
}
})