javascript-面试题

一、javascript的基本数据类型

基本数据类型:NumberStringBooleanundefinednullSymbol

引用数据类型:ObjectArrayRegExpDateFunction,特殊的基本包装类型(NumberStringBoolean)、以及单体内置对象(GlobalMath等)

二、如何判断不同的javascript数据类型
  1. typeoftypeof x ,基本类型除null返回object,其余全部返回自身的数据类型;引用类型除Function返回function,其余全部返回object

  2. instanceofA instanceof B,用来判断A是否是B的实例,检测的是原型,而不是属于那种类型

  3. toString:是用Object.prototype.toString.call(xxx)

    Object.prototype.toString.call('qqq') // [object String]
    
三、undefinednull有什么区别

undefined:表示缺少值,应该有值但还未赋值

  1. 变量被声明了,但没有赋值时,就等于undefined
  2. 调用函数时,应该提供函数参数而没有提供事,参数等于undefined
  3. 对象没有赋值的属性,值为undefined
  4. 函数没有返回值时,默认返回undefined

null:表示没有值,不应该有值

  1. 作为函数参数,表示该函数的参数不是对象
  2. 作为对象原型链的终点
四、数组对象有哪些常用方法

修改器方法:修改原始数组

  1. pop():删除数组最后一个元素,并返回这个元素
  2. shift():删除数组第一个元素,并返回这个元素
  3. unshift():在数组的开头增加一个或多个元素,并返回数组的新长度
  4. push():在数组的末尾增加一个或多个元素,并返回数组的新长度
  5. reverse():对数组进行逆序排序
  6. sort():对数组进行排序并返回当前数组
  7. splice():在任意位置给数组删除或者添加元素

访问器方法:不修改原始数组

  1. concat():返回一个组合而成的数组
  2. join():拼接数组元素形成一个字符串
  3. slice():截取当前数组中的一段元素组成一个新数组
  4. indexOf():返回数组中第一个与指定值相等的元素的索引,找不到则返回-1
  5. lastIndexOf():从数组最后一个元素往前找与指定值相等的元素的索引,找不到则返回-1
  6. forEach():为数组的每一个元素执行一次回调,最终返回undefined
  7. every():为数组的每一个元素都满足测试函数,则返回true,否则返回false
  8. some():数组中只要有一个函数满足测试条件,则返回true,否则返回false
  9. filter():将所有在过滤函数中返回true的元素组成一个新数组返回
  10. map():返回一个由回调函数的返回值组成的新数组
五、javascript创建对象的方式
  1. 对象字面量

    let obj = {}
    
  2. new Object构造函数

    let obj = new Object()
    
  3. 工厂模式

    function Person(name,age){
    	var o = new Object()
    	o.name = name
    	o.age = age
        o.say = function(){
            console.log(o.name)
        }
    	return o
    }
    let person = Person('hello',18)
    

    缺点:每次通过Person创建对象时,所有的say方法都是一样的,但是却存储了多次,造成资源浪费

  4. 构造函数模式

    function Person(name,age){
    	this.name = name
    	this.age = age
        this.say = function(){
            console.log(this.name)
        }
    }
    let person = new Person('hello',18)
    

    缺点:这个模式隐式在最后return this,如果在创建对象的时候缺少new,那么在函数中的this指向window,添加为全局属性和方法,解决办法是根据return this的特性调用call或者apply指定this

  5. 原型模式

    function Person(){
    	Person.prototype.name = 'hello'
    	Person.prototype.say = function(){
    		console.log(this.name)
    	}
    }
    Person.prototype.friends = ['lili']
    let person = new Person()
    

    缺点:实现方法与属性的共享,可以动态添加属性,但没有办法创建实例自己的属性和方法,也没有办法传递参数

  6. 构造函数和原型结合

    function Person(name,age){
    	this.name = name
    	this.age = age
    }
    Person.prototype.say = function(){
    	console.log(this.name)
    }
    let person = new Person('hello',18)
    
六、怎么实现对对象的深拷贝和浅拷贝

区别JavaScript的浅拷贝和深拷贝并掌握两者的实现方法

七、什么是闭包,为什么要使用闭包

JavaScript闭包详解

八、介绍一下javascript原型,原型链,两者有何特点

简单了解一下JavaScript原型链

九、javascript如何实现继承

简单了解一下JavaScript原型链

十、new操作符具体都干了什么
  1. 创建一个空对象

    let obj = new Object()
    
  2. 链接到函数的原型

    obj.__proto__ = Func.prototype
    
  3. 属性和方法都被加入到this引用的对象中,绑定this

    let result = Func.call(this)
    
  4. 最后隐式的返回对象this

    return result
    
十一、同步和异步的区别,怎么异步加载javascript

同步模式:同步模式又称为阻塞模式,默认情况下javascript是会阻塞加载的,当前面的javascript请求没有处理和执行完时,会阻止浏览器后续代码的处理

异步模式:异步模式又称为非阻塞模式,浏览器在下载执行javascript的同时,还会继续执行后续页面的处理

异步加载javascript

  1. 动态添加script标签
  2. 给标签添加defer或者async属性,两者均能实现异步加载
    • defer:加载完之后会等html加载完毕之后再执行
    • async:在异步加载完马上开始执行
十二、跨域问题的产生,如何解决

前端跨域介绍及跨域解决方案

十三、对this的理解

研究this一般都是this的指向问题,核心就是**this永远指向调用它的对象**,除非改变this指向或者是箭头函数等特殊情况,在普通模式下,最外层的this指向window,严格模式下this指向undefined

十四、apply()call()bind()是做什么的,有什么区别

相同点:改变this指向

不同点

  1. apply():传入两个参数,第一个是作为函数的执行上下文,另一个是作为函数参数数组

    let obj = {name:'haha'}
    function func(firstName,lastName){
    	console.log(firstName + this.name + lastName)
    }
    func.apply(obj,[12]) // 1haha2
    
  2. call():传入两部分参数,第一个参数是作为函数的执行上下文,剩下部分是个列表,可接受多个参数

    let obj = {name:'haha'}
    function func(firstName,lastName){
    	console.log(firstName + this.name + lastName)
    }
    func.call(obj,'1','2') //1haha2
    
  3. bind():传入两部分参数,第一个参数是作为函数的执行上下文,剩下部分是个列表,可接受多个参数

    let obj = {name:'haha'}
    function func(){
    	console.log(this.name)
    }
    let funcx = func.bind(null,'xixi')
    funcx() // xixi
    

applycall都会调用函数立即执行,bind不会立即执行,而是返回一个改变上下文this指向的函数,原函数中的this没有改变;bind在传递参数的时候会将自己带过去的参数排在原函数参数之前

function func(a,b,c){
	console.log(a,b,c)
}
let funcx = func.bind(this,'xixi')
funcx(1,2) // xixi12
十五、什么是内存泄漏、内存溢出,哪些操作会造成内存泄漏

内存溢出:程序运行时需要的内存超过了剩余内存,造成内存溢出

内存泄漏:指一块被分配的内存既不能使用也不能回收,直到浏览器进程结束( 占用的内存没有及时释放 )

操作:闭包、循环引用、意外的全局变量、未被及时清理的定时器或者回调函数

十六、什么是事件代理,原理是什么

事件代理:将元素的事件委托给它的父级或者更外层的元素处理

原理:利用事件的冒泡机制实现的

优点:只需要将同类元素的事件委托给父级或者更外层的元素,不需要给所有的元素都绑定一个事件,减少内存占用和代码量,提升性能;且动态新增的元素无需重新绑定事件

十七、对AMDCMD的理解,有什么区别

两者都是为了解决浏览器模块化的问题而产生的

AMD:对应库函数Require.js,异步加载模块, 推崇依赖前置 ,默认API是一个当多个用,擅长在浏览器端

CMD:对应库函数Sea.js,同步加载模块, 推崇依赖就近API严格区分,推崇职责单一,擅长在服务器端

十八、对ES 6的了解

新增特性

  1. 声明变量的方式let const
  2. 变量赋值解构
  3. 字符串新增方法:includes()startsWith()endsWidth()
  4. 数组新增方法:Array.from()Array.of()entries()keys()values()
  5. 对象的简洁写法,新增方法Object.is()Object.assign()entries()keys
  6. 箭头函数、扩展运算符、函数参数默认值等
  7. 新的数据结构:MapSet
  8. Proxy代理
  9. Promise对象
  10. async函数、await命令
  11. class
  12. module体系模块的加载和输出方式
十九、箭头函数有什么特点

ES 6中允许使用箭头函数,特点如下:

  1. 函数体中的this对象,是定义时所在的对象,而不是调用时的对象
  2. 不可以当作构造函数,即不可使用new命令
  3. 不可以使用arguments对象,因为不存在,如果要用,可以使用rest对象(扩展运算符)
二十、Promise对象的了解

Promise对象

二十一、async函数和await命令

async函数:就是Generator函数的语法糖

  1. async函数返回一个Promise对象,可以使用then方法添加回调函数。当函数执行时,遇到await命令就会先返回,等异步操作完成,再接着执行函数体内后面的语句
  2. async函数内部return语句返回的值,会成为then方法回调函数的参数
  3. async函数返回的 Promise对象,必须等到内部所有 await命令后面的 Promise对象执行完,才会发生状态改变,除非遇到 return 语句或者抛出错误
  4. async函数内部抛出错误,会导致返回的Promise对象变为 reject状态。抛出的错误对象会被 catch方法回调函数接收到
function timeout(ms){
    return new Promise((resolve) => {
        setTimeout(resolve,ms)
    })
}
async function asyncFun(value,ms){
    await timeout(ms)
    console.log(value)
}
asyncFun('hello',1000)
console.log('会不会阻塞函数体外的代码执行')
//会不会阻塞函数体外的代码执行
//Promise {<pending>}
//hello

await命令:await命令后面是一个promise对象,返回该对象的结果;如果不是promise对象,直接返回对应的值;另一种情况是如果then方法后面是一个thenable对象,则等同于promise对象

  1. await命令后面是一个promise对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中
  2. 多个await命令后面的异步操作,如果不存在继发关系,最好同时触发
  3. await命令只能用在async函数中,否则会报错
二十二、exportexport default的区别

两者均可用于常量、对象、函数、文件、模块等的导出

区别exportexport default
导出区别在一个文件或者模块中导出,exportimport可以有多个export default只有一个
导入区别在别的文件导入,变量名不可更改,且需加{}在别的文件导入,变量名可随意更改,不用加{}
二十三、前端性能优化
措施解释
1、尽可能减少 http 请求减少请求速度就快,合并cssjs,背景图使用css sprites
2、使用CDN就近访问服务器,较少数据在网络上传输的时间
3、添加Expires头或者Cache-control使用缓存
4、压缩组件减少文件传输体积大小
5、将css样式放在页面上有些浏览器比如IEFireFox要等全部css加载完毕之后才会去渲染页面
6、将script脚本移到底部会阻塞页面的下载,阻塞并行下载数量
7、避免使用css中的Expressions避免使用表达式,减少执行时间
8、将javascriptcss独立成外部文件如果做了缓存那就减少次数请求了,而且还便于维护
9、减少DNS查询域名和ip地址之间的转换工作,称为域名解析也称为DNS查询,一次查询要耗费20~120ms,在查询结束前,不会下载该域名的任何东西,所以建议一个页面包含的域名数尽量控制在2~4
10、压缩javascriptcss减少体积,传输就快,显而易见(但是可读性没了)
11、避免重定向会减少 web 请求
12、移除重复脚本减少体积
13、配置实体标签ETags不懂,听说可以减少web应用带宽和负载
14、使ajax缓存无解释
二十四、对 JS 引擎执行机制的理解

明确两点:

  1. javascript是单线程语言
  2. javascript的事件循环(event loop)是javascript的执行机制

javascript将任务分为同步任务和异步任务,执行机制就是代码执行开始,遇到同步任务就依次放到主线程上,遇到异步任务就先放到任务队列中,等同步任务执行完毕之后,通过事件循环去轮询可执行的异步任务,则把它加入到主线程上执行

区分宏任务和微任务

宏任务:setTimeoutsetIntervalrequestAnimationFrameI/O

微任务:process.nextTickPromiseObject.observeMutationObserver

执行顺序:先同再异,先微再宏

二十五、for infor of区别

for in:遍历的是key

for of:遍历的是key对应的值 (对象使用for of会报obj is not iterable的错误)

参考链接

网站优化 14条–雅虎十四条优化原则

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值