《实战\BAT大牛带你横扫初级前端JavaScript面试》内容总结
一、JS基础知识
1. 请写出JS中使用typeof能得到的类型
- typeof undefined //undefined
- typeof ‘abc’ //string
- typeof true //boolean
- typeof {} //object
- typeof [] //object
- typeof null //object
- typeof window.alert //function
延伸:常见的内置函数以及内置对象有哪些?
内置对象(拥有属性和方法):String、Number、Array、Boolean、Object、Function、Error、Math、Date。。。
window 内置方法:alert、parseFloat、setTimeout、Number、
toString。。。。
2. 何时使用"= =",以及何时使用 “= = =”
if(obj.a == null){
//这里相当于obj.a === null || obj.a === undefined 的简写形式
}
除了上述情况下,一律使用"= = ="
3. JS中有哪些内置函数–数据封装对象(抛开浏览器环境,没有window、document等)
Object、Array、Boolean、Number、String、Function、Date、RegExp、Error
4. JS按存储方式区分变量类型
值类型(number、string),引用类型(地址传递:object、array)
5. 如何理解JSON
JSON是一种数据格式,也可以说是一种JS对象
api:
JSON.stringify({a:10,b:20})
JSON.parse('{"a":10,"b":20}')
6. 如何准确判断一个变量是数组类型
var arr = []
arr instanceof Array
7. 写一个原型链继承的例子
function Elem(id){
this.elem = document.getElementById(id)
}
Elem.prototype.html = function(val){
if(val){
this.elem.innerHTML = val
return this
}else{
this.elem.innerHTML
}
}
Elem.prototype.on = function(type,fn){
this.elem.addEventListener(type,fn)
}
var div1 = new Elem('div1')
div1.html('asdfg')
8. 描述new一个对象的过程
- 创建一个新对象
- this指向这个新对象
- 执行代码,即对this赋值
- 返回this
9. 说一下对变量提升的理解
- JS中,函数和变量的声明都将被提升到程序的最顶部
- JS中,变量可以先使用后声明
- 当函数声明和变量声明同时出现时
10. 说明this几种不同的使用场景
作为构造函数执行
function Foo(name){
this.name = name
}
var f= new Foo('esther') // this === f
f.name
作为一个对象的属性执行
var obj = {
name:'esther',
printName:function(){
console.log(this.name) //this === obj
}
}
obj.printName() //esther
作为普通函数执行
function fn(){
console.log(this) // this ===window
}
call apply bind(都是用来重定义 this 这个对象的)
function fn1(name,age){
alert(name)
console.log(this)
}
fn1.call({x:200},'esther','20')
fn1.apply({y:99},'lee',99)
fn1.bind({bind:999})('li',100)
11. 创建10个a标签,点击的时候弹出来对应的序号
var a;
for(let i = 1;i<=10;i++) {
a = document.createElement('a')
a.innerHTML = i + '<br/>'
a.addEventListener('click', function (e) {
e.preventDefault()
alert(i)
})
document.body.appendChild(a)
}
12. 如何理解作用域
- 全局作用域:对于最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的
- 局部作用域:和全局用域相反,局部作用域一般只在固定的代码片段内可访问到,对于函数外部是无法访问的
- 块级作用域:let、const
13. 实际开发中闭包的作用
- 闭包就是能够读取其内部函数以及其内部变量的函数,返回其内部函数。
- 作用是读取内部的变量,让这些变量的值始终保存在内存中不被修改。
function isFirstLoad(){
var list=[];
return function(option){
if(list.indexOf(option)>=0){ //检测是否存在于现有数组中,有则说明已存在
console.log('已存在')
}else{
list.push(option);
console.log('首次传入'); //没有则返回true,并把这次的数据录入进去
}
}
}
var ifl=isFirstLoad();
ifl("zhangsan");
ifl("lisi");
ifl("zhangsan");
14. 同步和异步区别?分别举一个例子
- 同步会阻塞代码执行,异步不会
- 例子:alert同步,setTimeout异步
15. 一个关于setTimeout的笔试题
console.log(1)
setTimeout(function(){
console.log(2)
},0)
console.log(3)
setTimeout(function(){
console.log(4)
},1000)
console.log(5)
运行结果:1 3 5 2 4
16. 前端使用异步场景有哪些?
- 定时任务:setTimeout、setInterval
- 网络请求:ajax请求、动态加载
- 事件绑定
17. 获取2017-06-10格式日期
function formatdate(date){
var d
if(!date){
d = new Date()
}else{
d = new Date(date)
}
return d.toLocaleDateString().split('/').map(item=>{
if(item.length<2){
return item = '0'+item
}else{
return item
}
}).join('-')
}
formatdate('2017.6.10') //2017-06-10
18. 获取随机数,要求是长度一致的字符串格式
function Random(){
return (Math.random()+'0000000000').slice(2,12)
}
Random()
19. 写一个能遍历对象和数组的通用forEach函数
function forEach(obj,fn){
if(obj instanceof Array){
obj.forEach((item,index,obj)=>{
fn(item,index,obj)
})
}else{
for(var key in obj){
fn(key,obj[key])
}
}
}
arr = [1,2,3]
ob = {x:111,y:999}
forEach(arr,function(item,idx))
forEach(ob,function(key,value){console.log(key,value)})
二、WEB-API
20. 编写一个通用的事件监听函数
function bindEvent(el,type,selector,fn){
if(fn == null){
fn = selector
sellector == null
}
el.addEventListener(type,function(e){
var target
if(selector){
target = e.target
if(target.matches(selector)){
fn.call(target,e)
}
}else{
fn(e)
}
})
}
21. 描述事件冒泡流程
- 当一个元素事件被触发时,同样的事件将会在这个元素的所有祖先元素中被触发
- 阻止冒泡:e.stopPropagation()
22. 对于一个无限下拉加载图片的页面,如何给每个图片绑定事件
- 使用代理
- 优点:绑定一次即可!减轻浏览器(内存、渲染)压力
23. 手动编写一个ajax,不依赖第三方库(本题出现率很高)
var xhr = new XMLHttpRequest()
xhr.open("GET","/api",false)
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
alert(xhr.responseText)
}
}
xhr.send(null)
24. 跨域的几种实现方式
- JSONP
- 服务器端设置http header
25. 描述一下cookie、sessionStorage和localStorage区别
本身用于客户端和服务端的通讯,本身有本地存储的这里是引用文字功能。
使用document.cookie = …获取和修改即可。
缺点:
存储量太小,只有4KB。所有http请求都带着,会影响获取资源的效率。
localStorage和sessionStorage是H5专门为存储而设计,最大容量5M
api简单易用
localStorage.setItem(key,value);
localStorage.getItem(key);
sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问
并且当会话结束后数据也随之销毁。因此sessionStorage不是一种持久化的本地存储,仅、是会话级别的存储。只允许同一窗口访问。
而localStorage用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。同源可以读取并修改localStorage数据。
26. DOM是哪种基本的数据结构
树
27. DOM常用的api有哪些
- 获取DOM节点,以及节点的property和Attribute
- 获取父节点,子节点
- 增删改查节点
28.DOM节点的attr和property的区别
- property只是一个JS对象的属性的修改
- attribute是对html标签属性的修改
面试中考BOM的内容不多
29. 如何检测浏览器的类型
navigator.userAgent
三、开发环境
30. IDE:webstorm、sublime、vscode、atom
千万不要说使用Dreamweaver、notpad++
31. git常用指令(git常用指令必须很熟练)
- git add .
- git chenckout XXX
- git commit -m “XXX”
- git push origin master
- git pull origin master
- git branch
- git checkout -b xxx / git checkout xxx
- git merge xxx
32. 上线和回滚基本流程
上线:
- 将测试完的代码提交到git版本库的master分支
- 将当前服务器的代码全部打包并记录版本号,备份
- 将master分支的代码提交覆盖线上服务器,并生成新版本号
回滚:
- 将当前服务器的代码全部打包并记录版本号,备份
- 将备份的上一个版本号解压,覆盖到线上服务器,并生成新版本号
四、运行环境
33. 从输入url到得到html的详细过程(经常考)(也可以问:加载一个资源的过程)
加载资源的形式
- 输入url(或跳转页面)加载html http://…
- 加载html中的静态资源
- 加载资源的过程
- 浏览器根据DNS服务器得到域名的IP地址
- 向这个IP的服务器发送http请求
- 服务器收到、处理并返回http请求
- 浏览器得到返回内容
34. window.onloaded和DOMContentLoaded的区别
- window.onloaded:页面全部资源加载完才会执行,包括图片、视频等
- DOM渲染完即可执行,此时图片、视频可能没加载完
35. 性能优化(综合性问题,没有变准答案,只关注核心点即可)
原则
多使用内存、缓存或者其他方法
减少CPU计算、减少网络
从哪里入手
加载页面和静态资源
页面渲染
加载资源优化
静态资源的压缩合并
静态资源缓存
使用CDN让资源加载更快
使用SSR后端渲染,数据直接输出到html中
渲染优化
CSS放前面,JS放后面
懒加载(图片懒加载,下拉懒加载更多)
减少DOM查询,对DOM操作做缓存处理
减少DOM操作,多个操作尽量合并在一起执行
事件节流
今早执行操作(如DOMContentLoaded)
懒加载例子
<img id="img1" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="preview.png" data-realclass="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="abc.png" />
<script>
var img1 = document.getElementById('img1')
img1.src = img1.getAttribute('data-realsrc')
</script>
事件节流例子
var textarea = document.getElementById('text')
var timeoutId
textarea.addEventListener('keyup',function(){
if(timeoutId){
clearTimeout(timeoutId)
}
timeId = setTimsout(function(){
//触发change
},100)
})
共同学习,写下你的评论
评论加载中...
作者其他优质文章