JavaScript面试题1
markdown源文件
提取码:x67n
1、get请求传参的误区
get请求对请求参数的大小有限制其实是一个误区。在http协议中并未规定get请求的参数大小限制,对get请求有限制的是浏览器或者是web服务器对URL的长度的限制。
2、js闭包
闭包的作用:
可以在外部读取到函数内的局部变量,并且使该局部变量一直存在于内存之中,不会污染全局变量(JavaScript的GC机制,当一个变量不在被引用时将会被回收,闭包就解决了局部变量被回收的问题。)
例子:
function a(){
var a=999 //注意这里必须使用var声明,如果没有var声明出来的是全局变量。
function b(){
alert(a)
}
return b
}
var c=a()
c()
//子函数所在的父函数的作用域不会被释放,也就是说a会一直保存在内存中。
3、类的创建和继承
类的创建
//类似一个构造函数
function animal(name){
this.name=name;
//实例方法
this.eat=function(){
console.log('eat food')
}
//原型方法
animal.prototype.sleep=function(){
console.log('--sleep--')
}
}
//实例化即可
继承:
基于原型链的继承,创造的实例既是父类的实例也是子类的实例。
缺点:无法多继承
//原型链继承
function dog(){} //先定义一个空对象
dog.prototype=new animal() //原型指向animal
dog.prototype.eat=function(){
console.log('--dog --eat--')
}
var d=new dog()
//d instanceof animal(true)
//d instanceof dog(true)
基于构造函数的继承,可以多继承,只能继承实例的方法和属性,无法继承原型上的属性和方法
function dog(){
animal.call(this)
}
组合继承:将上述两种方式组合起来,实例和原型的方法和属性都继承了。
寄生组合继承:砍掉父类的实例属性
function dog(){
animal.call(this)
}
(function(){
var Super=function(){}
Super.prototype=animal.prototype
dog.prototype=Super.prototype
})()
4、如何解决回调地狱
Promise、async、await具体的自己写,就不举例子了。
5、前端中的事件流
事件流是指从页面接收事件的顺序。
html和JavaScript的交互是通过事件驱动来实现的,标准的dom事件模型之中包括以下几个阶段:
- 事件捕获阶段(从外到里)
- 处于目标阶段
- 事件冒泡阶段(从里到外)
addventlistener函数是指定事件处理程序的操作,有三个参数,事件名,事件函数,和一个布尔值,而最后一个布尔值就决定了事件是在捕获阶段执行的还是在冒泡阶段执行的。true表示在捕获阶段执行,false表示在冒泡阶段执行。ie只支持冒泡阶段执行处理函数。
6、事件委托
事件委托指的是不在所要发生的dom上设置监听,而是在其父元素上设置监听函数,通过事件的冒泡机制来监听子元素的行为。比较适合动态元素的添加,且最新的添加元素也具有事件触发己制
7、懒加载和预加载的区别
预加载:提前加载,用户需要查看时只需要在缓存中取出即可
懒加载:是一种前端对于服务端的优化,减少请求数或者是延迟请求,可以缓解服务器的压力。
8、mouseover和mouseenter的区别
mouseover是指鼠标移入元素或者是子元素时都会触发事件,会有一个重复触发,会冒泡。
mouseenter是则是鼠标移入元素就会触发,移入子元素则不会重复触发,不具有冒泡
9、js的new关键字执行了什么
新建一个空对象,对象原型指向构造函数的prototype,执行构造函数后返回这个对象
10、this指向改变
bind返回一个函数,不会直接执行,apply和call就参数不同,第一个this改变指向的对象,apply第二个参数是数组,根据要改变的函数的形参来赋值,call则是后面的是一个参数列表
实例:
var obj = {
name : '111'
}
function func(firstName, lastName){
console.log(firstName + ' ' + this.name + ' ' + lastName);
}
func.apply(obj, ['A', 'B']); //apply
func.call(obj,'A','B');//call
var b=func.bind(obj)//bind
11、js的各种位置
offsetHeight:可视高度,包含border和滚动条
clientHeight:可视高度,包含border和滚动条
scrollHeight:表示所有区域,包含因为滚动被隐藏的区域
clientTop:边框border的厚度,默认为0
scrollTop:滚动后被隐藏的高度
12、JavaScript GC机制(垃圾回收机制)
js中只有两种变量,全局变量和局部变量,全局变量的生命周期会一直存在直到页面被卸载。局部变量的声明周期是从声明开始知道函数体结束。有一种特殊的局部变量不会被内存回收,就是闭包,因为函数的局部变量被外部函数所使用。
垃圾回收的两种机制:
1、标记清楚
就字面意思,进入环境就给一个标记,离开环境后就给一个离开标记,垃圾回收器会回收标记为离开的变量。
举例:
function a(){
var c=2 //进入环境
console.log(c)
}
a();//离开环境
2、引用计数法
当值被引用时,则计数加1,如果引用这个值的变量又取得了另一个新的值时,这时候就-1,垃圾回收器运行时,就会对引用计数为0的值进行回收。
13、commonjs
Commonjs:开始于服务器端的模块化,同步定义的模块化,每个模块都是一个单独的作用域,模块输出,modules.exports,模块加载require()引入模块。
14、监听对象属性
es5中可以通过object.defineProperty
Object.defineProperty(user,'name',{
set:function(key,value){}
})
如果user中没有name属性就不能监听。
es6中的监听(vue后来重写的对象监听就是用的这个方法)
var user =new Proxy({},{
set:function(tartget,prop,value){
},
get:function(target,prop){
return target[prop]
}
})
15、==、===和Object.is的区别
==非严格相等,类型不同会进行类型转换。
===严格相等,不会进行类型转换,一定要相同类型且值也要相等才是true
Object.is主要是判断NaN和+0,-0的