JS由哪三部分组成
1.ECMAScript:JS的核心内容,描述了语言的基础语法,比如var,for,数据类型(数组、字符串)
2.文档对象模型(DOM):DOM把整个HTML页面规划为元素构成的文档
3.浏览器对象模型(BOM):对浏览器窗口进行访问和操作
JS有哪些内置对象
1.Math有哪些方法:abs()、max()、min()、sqrt()
2.New Date有哪些方法:getFullYear、getMonth、getDate()、getDay()、getHours()、getMinutes()、getSeconds()
3.Array有哪些方法:map、foreach、shift、unshift、pop
4.String有哪些方法:cancat、length、slice、split
操作数组的方法有哪些
push()、pop()、sort()、splice()、unshift()、shift()、reverse()、concat()、join()、map() 、filter()、ervery()、some()、reduce()、isArray()、findIndex()
哪些方法会改变原数组?
push()、pop()、unshift()、shift()、sort()、reverse()、splice()
JS对数据类的检测方式有哪些
typeof() 对于基本数据类型的判断没问题,对于引用数据类型不可以
instanceof 只能判断引用数据类型,不能判断基本数据类型
constructor 几乎可以判断基本数据类型和引用数据类型,如果声明了一个构造函数,并把它的原型指向了Array就不可以
object.prototype.toString().call() 基本数据类型和引用数据类型都可以判断
说一下闭包,闭包有什么特点
闭包:函数嵌套函数,内部函数的变量可以访问外层函数的变量,就会产生闭包
特点:可以重复利用变量,并且这个变量不会污染全局的一种机制,这个变量始终保存在内存中,不会被垃圾回收机制回收
缺点:闭包较多时,会消耗内存,导致页面的性能下降,在ie浏览器中才会导致内存泄露,除非手动把变量设置为null
使用场景:防抖、节流、定时器,函数嵌套函数为了避免全局污染的时候
你对内存泄漏怎么理解
JS里已经分配内存地址的对象,但是由于长时间没有释放或者没办法清除,造成长期占用内存的现象,会让内存资源大幅浪费,最终导致运行速度慢,甚至崩溃的情况。
垃圾回收机制
因素:一些为生命直接赋值的变量;一些未清空的定时器;过度的闭包;一些引用元素没有被清除。
事件委托是什么
又叫事件代理,原理就是利用了事件冒泡的机制来实现,也就是说把子元素的事件绑定到了父元素的身上,如果子元素阻止了事件冒泡,那么委托也就不成立
阻止事件冒泡:event.stopPropagation(),addEventListener('click',函数名,true/false) 默认是false(事件冒泡),true(事件捕获)
好处:提高性能,减少事件的绑定,也就减少了内存的占用。
基本数据类型和引用数据类型的区别
基本数据类型:String Number Boolean undefined null
基本数据类型保存在栈内存当中,保存的就是一个具体的值
引用数据类型(复杂数据类型):Object Function Array
保存在堆内存当中,声明一个引用类型的变量,它保存的是引用类型数据的地址
假如声明两个引用类型同时指向了一个地址的时候,修改其中一个那么另外一个也会改变
说一下原型链
每个对象都有一个属性叫__proto__,它是一个对象,代表这个对象的构造函数的原型对象,这个对象也会有构造函数,顺着这个构造方向一层一层往上找的机制就叫做原型链
new操作符具体做了什么
1.先创建一个空对象
2.把空对象和构造函数通过原型链进行连接
3.把构造函数的this绑定到新的空对象身上
4.根据构建函数返回的类型判断,如果是值类型,则返回对象,如果是引用类型,就要返回这个引用类型
function newfun(fun, ...args) {
// 先创建一个空对象
let obj = {};
// 把空对象和构造函数通过原型链进行连接
obj.__proto__ = fun.prototype;
// 把构造函数的this绑定到新的空对象身上
const result = fun.apply(obj, args);
// 根据构造函数返回的类型判断,如果值类型,则返回对象,如果是引用类型,就要返回这个引用类型
return result instanceof Object ? result : obj;
}
function Person(name) {
this.name = name;
}
Person.prototype.say = function () {
console.log('123456');
};
const p1 = newfun(Person, '张三');
p1.say();
console.log(p1);
js如何实现继承
1.原型链继承:将待继承对象的prototype指向被继承对象的prototype,就可以访问原型上的属性和方法了
优点:写法方便简洁,便于理解
缺点:对象实例共享所有继承的属性和方法,无法向父类函数传参
2.借用构造函数继承:在子类构造函数的内部调用父类构造函数;使用 apply 或 call的方法将父对象的构造函数绑定在子对象上。
优点:解决了原型链实现继承不能传参和父类的原型共享问题。
缺点:方法都在构造函数中定义,因此无法实现函数的复用。在父类的原型中定义方法,在子类中是不可见的,结果所有类型都只能使用构造函数模式
3.组合式继承:将原型链和借用构造函数组合到一块。使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承。既通过在原型上定义方法实现了函数的复用,又能够保证每个实例都有自己的属性
优点:就是解决了原型链继承和借用构造函数继承造成的影响
缺点:是无论在什么情况下,都会调用两次父类构造函数,一次实在创建子类原型的时候,另一次是在子类构造函数的内部
4.es6的class继承:class通过extends关键字实现继承,其实质是先创造出父类的this对象,然后用子类的构造函数修改this,子类的构造方法中必须调用super方法,且只有在调用super()之后才能使用this,因为子类的this对象是继承父类的this对象,然后对其进行加工,而super方法表示的是父类的构造函数,用来新建父类的this对象
js设计原理
JS引擎 运行上下文 调用栈 事件循环 回调
js中关于this指向的问题
1.全局对象中的this指向是window
2.全局作用域或普通函数this指向全局window
3.在不是箭头函数的情况下谁调用this就指向谁
4.new关键词改变了this指向
5.apply、call、bind改变了this指向
6.箭头函数本身没有this指向,如果有this指向是父级作用域
7.匿名函数因为具有全局性,匿名函数中的this指向window
Script标签里的async和defer有什么区别
当没有async和defer这两个属性的时候
浏览器会立刻加载并执行指定的脚本
有async
加载和渲染后面元素的过程将和script的加载和执行并行进行(异步)
有defer
加载和渲染后面元素的过程将和script的加载并行进行(异步),但是它的执行事件要等
所有元素解析完成之后才会执行
setTimeout最小执行时间是多少?
HTML5规定的内容:
setTimeout最小执行时间是4ms
setInterval最小执行时间是10ms注意浏览器不同最小的时间也会有不同
ES6的新特性有哪些?
1.let、const块级作用域
2.结构赋值
3.基本数据类型(symbol)
4.对象和数组新增了扩展运算符
5.promise
6.async、await
7.Set和Map数据结构
8.箭头函数
9.class类的语法糖
call,aply,bind三者有什么区别?
都是改变this指向和函数的调用,call和apply的功能类似,只是传参的方法不同
call方法传的是一个参数列表
apply传递的是一个数组
bind传参后不会立刻执行,会返回一个改变了this指向的函数,这个函数还是可以传参的
call方法的性能要比apply好一些,所以call用的更多一点
用递归的时候有没有遇到什么问题?
如果一个函数内可以调用函数本身,那么这个就是递归函数
函数内部调用自己
特别注意:写递归必须要有退出条件return
如何实现一个深拷贝?
深拷贝就是完全拷贝一份新的对象,会在堆内存中开辟新的空间,拷贝的对象被修改后,原对象不受影响
主要针对的是引用数据类型
1.扩展运算符
2.JSON.parse(JSON.stringify())
3.利用递归函数实现
说一下事件循环?
JS是一个单线程的脚本语言
主线程 执行栈 任务队列 宏任务 微任务
主线程先执行同步任务,然后才去执行任务队列里的任务,如果在执行宏任务之前有微任务,那么要先执行微任务
全部执行完之后等待主线程的调用,调用完之后再去任务队列中查看是否有异步任务,这样一个循环往复的过程就是
ajax是什么?怎么实现的?
创建交互式网页应用的网页开发技术
在不重新加载整个网页的前提下,与服务器交换数据并更新部分内容
通过XmlHttpRequest对象向服务器发送异步请求,然后从服务器拿到数据,最后通过JS操作DOM更新页面
1.创建XmlHttpRequest对象 xmh
2.通过xmh对象里的open()方法和服务器建立连接
3.构建请求所需的数据,并通过xmh对象的send()发送给服务器
4.通过xmh对象的onreadystate chansge事件监听服务器和你的通信状态
5.接收并处理服务器响应的数据结果
6.把处理的数据更新到HTML页面上
get和post有什么区别?
1.get一般是获取数据,post一般是提交数据
2.get参数会放在url上,所以安全性比较差,post是放在body中
3.get请求刷新服务器或退回是没有影响的,post请求退回时会重新提交数据
4.get请求时会被缓存,post请求不会被缓存,get是幂等性,post是非幂等性
5.get请求会被保存在浏览器历史记录中,post不会
6.get请求只能进行url编码,post请求支持很多种
promise的内部原理是什么?它的优缺点是什么?
Promise对象,封装了一个异步操作并且还可以获取成功或失败的结果
Promise主要就是解决回调地狱的问题,之前如果异步任务比较多,同时他们之间有相互依赖的关系,
就只能使用回调函数处理,这样就容易形成回调地狱,代码的可读性差,可维护性也很差
有三种状态:pending初始状态 fulfilled成功状态 rejected失败状态
状态改变只会有两种情况,
pending -> fulfilled; pending -> rejected 一旦发生,状态就会凝固,不会再变
首先就是我们无法取消promise,一旦创建它就会立即执行,不能中途取消
如果不设置回调,promise内部抛出的测u哦呜就无法反馈到外面
若当前处于pending状态时,无法得知目前在哪个阶段。
原理:
构造一个Promise实例,实例需要传递函数的参数,这个函数有两个形参,分别都是函数类型,一个是resolve一个是reject
promise上还有then方法,这个方法就是来指定状态改变时的确定操作,resolve是执行第一个函数,reject是执行第二个函数
promise和async await的区别是什么?
1.都是处理异步请求的方式
2.promise是ES6,async await 是ES7的语法
3.async await是基于promise实现的,他和promise都是非阻塞性的
优缺点:
1.promise是返回对象我们要用then,catch方法去处理和捕获异常,并且书写方式是链式,容易造成代码重叠,不好维护,async await 是通过tra catch进行捕获异常
2.async await最大的优点就是能让代码看起来像同步一样,只要遇到await就会立刻返回结果,然后再执行后面的操作
promise.then()的方式返回,会出现请求还没返回,就执行了后面的操作
浏览器的存储方式有哪些?
1.cookies
H5标准前的本地存储方式
兼容性好,请求头自带cookie
存储量小,资源浪费,使用麻烦(封装)
2.localstorage
H5加入的以键值对为标准的方式
操作方便,永久存储,兼容性较好
保存值的类型被限定,浏览器在隐私模式下不可读取,不能被爬虫
3.sessionstorage
当前页面关闭后就会立刻清理,会话级别的存储方式
4.indexedDB
H5标准的存储方式,,他是以键值对进行存储,可以快速读取,适合WEB场景
token存在sessionstorage还是loaclstorage?
token:验证身份的令牌,一般就是用户通过账号密码登录后,服务端把这些凭证通过加密等一系列操作后得到的字符串
1.存loaclstorage里,后期每次请求接口都需要把它当作一个字段传给后台
2.存cookie中,会自动发送,缺点就是不能跨域
如果存在localstorage中,容易被XSS攻击,但是如果做好了对应的措施,那么是利大于弊
如果存在cookie中会有CSRF攻击
javascript的数据类型有哪些?
基础数据类型:
- Number(数值,包含NaN)
- String(字符串)
- Boolean(布尔值)
- Undefined(未定义/未初始化)
- Null(空对象)
- Symbol(独一无二的值,ES6 新增)
- BigInt (大整数,能够表示超过 Number 类型大小限制的整数,ES 2020新增)
引用数据类型:
- Object
- Array
- function
- Date
- RegExp