2019年最新前端面试题,自我梳理(JS和CSS部分)

面试题todolist

1.简述异步和同步的区别 √ *****

​ JS是单线程的,分主线程和队列事件,同步事件在主线程中执行,前一个执行完才能执行后一个,异步事件在队列中,等待主线程的事件执行结束后才开始执行。

2.JS的基本数据类型 √

​ 1.undefined 2.null 3,number 4,string 5.symbol 6.boolean (引用类型 object)

3.简单概述 div元素和span元素的区别 ×

​ div:块元素独占一行 有标准盒模型 包括margin border padiing 和content 宽度没设置默认100%

​ span:行内元素 和其他元素都在同一行 行内元素只能容纳文本或者其他行内元素

​ 行内元素设置要注意:1.设置宽高都无效 ,但是可以通过line-height来设置

​ 2.设置margin 和 padding 只有左右有效,上下无效

4.什么是css预处理和后处理器 ×

​ css预处理:利用sass或者less等各种css预处理器,对web页面样式进行编程,然后在编译成正常的css文件

​ 优势:1.解决代码冗余

​ 2.提高样式的可维护性

​ 3.提供css层缺失的样式层复用机制

​ css后处理器:对css进行处理,并且最终生成css的预处理器。

5.css优先级算法如何计算 √

​ 1.元素选择器 0 2.类选择器 10 3.ID选择器 100 4.内联元素1000 5.!important权重最高

6.this指向问题 √ ******

​ this 是 JS 函数中的一个关键词

​ 1.在严格模式下this指向是undefined

2. 在标准函数中指向的是window
3. 在事件中,谁触发事件就指向谁
4. 在构造函数中,this指向的是实例对象
5. 在回调函数中,this指向的是Window
6. 在箭头函数中,this指向的是父级

7.Display有哪些值以及作用 √

​ 1. display:none 元素隐藏

2. display:block    元素变成块元素
3. display:inline-block  变成行内块元素
4. display:inline   变成行内元素
5. display:flex    弹性盒

8.js的作用域链 以及作用域 ×

​ JS中作用域分成全局作用域以及局部作用域 window的内置属性都拥有全局作用域

​ 2.局部作用域 只有固定的代码内才能被访问到

作用域链:一般情况下变量取值在创建这个变量的函数作用域中进行取值,如果取不到就会向上级作用域去查,直到全局作用域,这么一个查找的过程就叫作用域链

9.模块化的好处以及实现方式 ×

​ 解决命名冲突:提高复用性;提高代码的可维护性 (解决冲突和依赖问题)

​ 实现方法:AMD CMD COMMONJS ES6 Module

commonjs规范:每个js文件就是一个独立的模块 (node.js就是利用common.js规范)

​ commonjs规范 主要适用于服务器端编程,所以 采用的是同步加载模块的策略

AMD:是异步模块定义,从commonjs中诞生,requirejs就是基于AMD规范

CMD:sea.js 就是用CMD规范实现的 不过是淘宝内容使用的

10.Document.write和innerHTML的区别 ×

​ document.write是直接写入到页面的内容流,如果之前没有调用document.open,浏览器会自动调用open,每次关闭之后重新调用这个函数,会导致页面被重写

​ document.innerhtml是将内容写入某个dom节点,不会导致页面全部的重绘

11.什么是window对象,什么是document对象 ×

​ window是一个顶层的对象,而不是一个对象的属性 是浏览器的窗口

​ 而document对象是 window对象下的一个对象属性

12.Map ,filter,reduce各自的作用 ×

​ MAP遍历原数组,里面可以进行一些逻辑运算,得到一组新的数组

​ Filter 过滤 遍历数组 里面写一些逻辑 返回出true的数组 可以过滤一些不需要的元素

Reduce  
reduce可以接受两个参数,reduce接受的第一个参数是一个方法,该方法可以接受四个参数,第一个参数为上一次函数调用的返回值(第一次调用时默认是数组的第一个元素),第二个参数为当前被遍历的元素,第三个参数为当前遍历元素的下标,第四个参数为执行reduce方法的原数组,reduce接受的第二个参数是第一个参数方法第一次调用的返回值的初始值(默认是数组的第一个元素)。

reduce可以遍历调用该方法的数组并使用传入参数方法,返回遍历完成后最终的执行结果,不会修改原数组。

13.什么是BFC ×

BFC,块级格式化上下文,一个创建了新的BFC的盒子是独立布局的,盒子里面的子元素的样式不会影响到外面的元素。在同一个BFC中的两个毗邻的块级盒在垂直方向(和布局方向有关系)的margin会发生折叠。

BFC拥有一个独立的渲染空间,有自己的布局方式,外部无法干涉

​ 如何触发BFC:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lx1xYXwl-1577322766033)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1575622808572.png)]

14.什么是DPR ×

​ (移动端适配)像素比:设备物理像素和独立像素的比

15.简单描述下对HTML语义化的理解 ×

​ html 语义化就是让页面的内容结构化,便于对浏览器和搜索引擎进行解析,在没有CSS样式的时候也是以一种文档格式显示,便于阅读。同时搜索引擎的爬虫依赖于标记来确定上下文和各个关键字的权重,有利于SEO,使阅读源代码的人对网站更易于分块,便于阅读维护理解

(1.内容结构化,便于搜索引擎解析 2.在没有css的情况下,便于阅读 3.有利于搜索引擎依赖标签来确定各个关键字的权重,有利于seo 4.让读源代码的人更容易对网页进行阅读维护)

16.Doctype作用,标准模式和兼容模式的区别 ×

​ Doctype是document type(文档类型)缩写 写在文档的最前面,处于标签之前,不是HTML标签

​ 主要的作用是告诉浏览器的解析器是用那种HTML规范或者XHTML规范来解析页面

​ 标准模式与兼容模式的区别:Standards—标准模式,用于呈现遵循最新标准的网页,而Quirks—兼容模式,用于呈现为传统浏览器而设计的网页。

17.ES6的继承 × *********

1.原型继承:

​ 1.1借助构造函数实现继承 ---------在子类构造函数中,把父元素的实例对象的this指向改变(缺点:只能继承父类构造函数的属性,没办法继承父类原型上的方法)

function Parent(){
     this.name='大明'
 };
 Parent.prototype.say=function(){
      alert(this.name);
}
 function Child(){
     Parent.call(this);   //this表示Child,继承Parent的属性和方法
     this.type='child';
 }
 var p=new Child();
 console.log(p.name);    //大明
 console.log(p.type);    //child
 p.say();    //TypeError

​ 1.2借助原型链来实现继承

​ 把父类的构造函数实例化给 子类的原型对象(可以继承父类的方法和父类原型上的方法,缺点:当父类中包含引用类型的属性值,改变其中一个实例的引用属性,其他的实例也会跟着改变)

 function Parent(){
     this.name='大明';
     this.eat=[1,2,3];    //引用数据类型
  };
  Parent.prototype.say=function(){
       alert(this.name);
 }
  function Child(){
      this.type='child';
  }
  Child.prototype=new Parent();
  var p=new Child();
  console.log(p);   //name、type属性和say方法都有
  var p1=new Child();
  var p2=new Child();
  p1.name='小明';
  console.log(p1.name,p2.name);   //小明  大明
  p2.eat.push(4);
  console.log(p1.eat,p2.eat);    //[1,2,3,4]   [1,2,3,4]

​ 组合方式:结合构造函数继承和原型链继承 (可以解决以上两种弊端)

2.类继承:

​ class实现继承的核心在于使用extends表明继承来自哪个父类,并且在子类构造函数中必须调用super。

class Parent {
    constructor(value) {
        this.val = value
    }
    getValue() {
        console.log(this.val)
    }
}
class Child extends Parent {
    constructor(value) {
        super(value)
        this.val = value
    }
}
let child = new Child(2)
child.getValue()//2
console.log(child instanceof Parent)//true

18.解决异步的方法

传统方案:

1.回调函数:

**优点:**简单,容易理解和 部署。

**缺点:**不利于代码的阅读,和维护,各部分之间高度耦合,流程会很混乱,而且每一个任务只能指定一个回调函数,会产生回调地狱。

2.事件驱动 :

**优点:**比较容易理解,可以绑定多个事件,每一个事件可以指定多个回调函数,而且可以去耦合,有利于实现模块化。

**缺点:**整个程序都要变成事件驱动型,运行流程会变得不清晰。

主流方案:

1.Promise: 解决的问题(地狱回调,异步处理)

Promise是ES6新增的语法,有三种状态,(pending等待,已经成功resolved,已经失败reject------状态不能实现逆向转换)
使用Promise的时候 需要实例化Promise ,而Promise函数中提供了两个参数 resolve,reject 成功的时候执行resolve 失败执行reject
同时有then方法和catch方法 then方法的回调中执行 resolve传入的参数 catch 执行的是reject 或者then直接接受两个函数分别对应resolve和reject状态的回调

1.2.Promise.all
Promise.all可以把多个Promise实例包装成一个新的Promise实例,成功的时候返回一个结果的数组,失败的时候返回首先失败的reject的值
Promise.all 可以处理并发的数据请求

1.3.Promise.race
返回获得结果快的数据,不管结果成功还是失败,应用场景较少

2.generator
优势:1.通过yield 语句 可以实现分段执行,可以进行暂停
2.可以控制每个阶段和每个阶段的返回值
3.通过next()方法的返回值的done属性可以知道是否执行到最后,如果是false表示还没执行到最后,如果是true表示语句执行到最后
(把异步操作写在yield语句里,通过Next方法来处理异步操作)

3.async await是ES7新增的

generator的语法糖 async会返回一个promise对象
用法:await只能用在async函数中---------await表示等待异步操作返回结果,再继续执行下去--------await后面跟着的一般是一个promise对象

async 会将其后的函数的返回值封装成一个 Promise 对象,而 await 会等待这个 Promise 完成,并将其 resolve 的结果返回出来。

19.简答概述下cookie,localstorage,sessionstorage

​ 首先总的来说,三者都是用于数据存储数据的手段,都是存在浏览器上

​ 1.cookie是服务器端存储在客户端的数据,帮助服务器分担压力,但是大小不超过4K

​ 2.localstorage和sessionstorage都是Web存储,大小大概在5M左右,完全存储在客户端,是本地存储的方式

​ 3.localStorage属于永久性存储,而sessionStorage属于当会话结束的时候,存储的值会被清空,而cookie是通过设置过期时间来存储的。

20. 分别描述下 var let const的区别

var

​ 1.变量的值是可以改变的

​ 2.变量是松散型的(自动识别的类型)

​ 3.变量会写入内存

​ 4.var变量前置访问会输出undefined

​ 5.可以同时定义多个变量

let

​ 1.有独立的作用域

​ 2.前置访问会报错

​ 3.不允许在相同的作用域内,重复声明同一个变量

​ 4.ES6允许块级作用域的任意嵌套,外层无法读取内层作用域的变量,反之可以

const

​ 1.const声明一个只读的常量。一旦声明,常量的值就不能改变。

21.浏览器的渲染机制

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sa3b7Llx-1577322766035)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1575892508522.png)]

22.一次完整的HTTP请求的过程

域名解析 —> 与服务器建立连接 —> 发起HTTP请求 —> 服务器响应HTTP请求,浏览器得到html代码 —> 浏览器解析html代码,并请求html代码中的资源(如js、css、图片) —> 浏览器对页面进行渲染呈现给用户

23.JS判断数据类型的方法有哪些

1.typeof

数字Number,布尔值Boolean,字符串String,函数Function,对象Object,Undefined)这一些数据类型在typeof 下都被精准的解释,只有数组和null的数据类型不够精准。那么如何才能获取到 数组 和 null 的精准数据类型。这就用到下面这种方法。  (引用类型的数据类型都显示的是object不够准确)

2.instanceof (只能对引用类型数据进行精确判断)

console.log(2 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false 
console.log('str' instanceof String);                // false  
console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true    
// console.log(undefined instanceof Undefined);
// console.log(null instanceof Null);

​ 返回布尔值 判断前面的数据是不是后面的构造函数的实例对象

只有引用数据类型(Array,Function,Object)被精准判断,其他(数值Number,布尔值Boolean,字符串String)字面值不能被instanceof精准判断。我们来看一下 instanceof 在MDN中的解释:instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。其意思就是判断对象是否是某一数据类型(如Array)的实例
3.constructor

console.log((2).constructor === Number);
console.log((true).constructor === Boolean);
console.log(('str').constructor === String);
console.log(([]).constructor === Array);
console.log((function() {}).constructor === Function);
console.log(({}).constructor === Object);

用costructor来判断类型看起来是完美的,然而,如果我创建一个对象,更改它的原型,这种方式也变得不可靠了。

function Fn(){};
 
Fn.prototype=new Array();
 
var f=new Fn();
 
console.log(f.constructor===Fn);    // false
console.log(f.constructor===Array); // true 

4.object.prototype.toString.call()

var a = Object.prototype.toString;
 
console.log(a.call(2));
console.log(a.call(true));
console.log(a.call('str'));
console.log(a.call([]));
console.log(a.call(function(){}));
console.log(a.call({}));
console.log(a.call(undefined));
console.log(a.call(null));

改变call的指向去判断数据类型

24.HTTP的状态码

1.信息类状态码

2.成功状态码

3.重定向类状态码

4.客户端错误状态码

5.服务端错误状态码

25.常用那几种浏览器测试?有哪些内核(Layout Engine)?

浏览器:IE,Chrome,FireFox,Safari,Opera。

内核:Trident,Gecko,Presto,Webkit。

26.清除浮动有哪些方式?比较好的方式是哪一种?

1.给浮动的元素的祖先元素加高度。

2.结尾处加空div标签clear:both。

3.父级div定义伪类:after和zoom。 (最好的方法)

4.父级div定义overflow:hidden。

5.父级div定义overflow:auto。

6.父级div也浮动,需要定义宽度。

7.父级div定义display:table。

8.结尾处加br标签clear:both。

27.请写出一些前端性能优化的方式,越多越好

1.减少dom操作
2.部署前,图片压缩,代码压缩
3.优化js代码结构,减少冗余代码
4.减少http请求,合理设置 HTTP缓存
5.使用内容分发cdn加速
6.静态资源缓存
7.图片延迟加载

28.什么情况会触发重排和重绘?

添加、删除、更新 DOM 节点
通过 display: none 隐藏一个 DOM 节点-触发重排和重绘
通过 visibility: hidden 隐藏一个 DOM 节点-只触发重绘,因为没有几何变化
移动或者给页面中的 DOM 节点添加动画
添加一个样式表,调整样式属性
用户行为,例如调整窗口大小,改变字号,或者滚动

29.DOM怎样添加、移除、移动、复制、创建和查找节点。

创建新节点
  createDocumentFragment()创建一个DOM片段
  createElement() 创建一个具体的元素
  createTextNode() 创建一个文本节点
  添加、移除、替换、插入
  appendChild()
  removeChild()
  replaceChild()
  insertBefore() 在已有的子节点前插入一个新的子节点
   查找
  getElementsByTagName() 通过标签名称
  getElementsByName() 通过元素的Name属性的值(IE容错能力较强,会得到一个数组,其中包括id等于name值的)
  getElementById() 通过元素Id,唯一性

30.null和undefined的区别?

(nullnull)(nullundefined)(undefined==null) null跟undefined都是0 NAN跟什么都不等

**Number()特殊情况为0 1. 空字符串 2,NULL 空对象 **

3.false 4.0

boolean 在 1.0 2.null 3.undefined 4.‘’ 5.NAN 返回的都是false

undefined: 表示"缺少值",就是此处应该有一个值,但是还没有定义

(1)变量被声明了,但没有赋值时,就等于undefined。
  (2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。
  (3)对象没有赋值的属性,该属性的值为undefined。
  (4)函数没有返回值时,默认返回undefined。
null:表示"没有对象",即该处不应该有值。
  (1) 作为函数的参数,表示该函数的参数不是对象。
  (2) 作为对象原型链的终点

31.解决跨域的方式

1.JSONP

原理:在HTML标签里,一些标签比如script、img这样的获取资源的标签是没有跨域限制的

2. CORS跨域

后端修改请求头*

header(‘Access-Control-Allow-Origin:*’);允许访问的网址
header(‘Access-Control-Allow-Method:POST,GET’);允许访问的方式

3.反向代理

4.使用window.name来进行跨域

5.通过修改document.domain来跨子域

6.使用HTML5中新引进的window.postMessage方法来跨域传送数据(ie 67 不支持)

32.AJAX AXIOS FETCH区别

1.ajax :原生的api 如果有多个请求,并且有前后关系的话,容易产生回调地狱,需要进行封装

**2.axios: **

1.从浏览器中创建 XMLHttpRequest

2.支持 Promise API
3.客户端支持防止CSRF (跨站请求伪造,假的请求,利用token可以防止)
4.提供了一些并发请求的接口(重要,方便了很多的操作)
5.从 node.js 创建 http 请求
6.拦截请求和响应
7.转换请求和响应数据
8.取消请求
9.自动转换JSON数据

3.fetch

1. 原生js提供,可以说ajax封装版本,用起来简易

2. 符合模块化思想

3. 在浏览器中呈现的fetch字样

4. fetch也是promise

5. fetch返回值是没有经过封装的,安全度比axios要低

33.CSS哪些属性可以继承?

css继承特性主要是指文本方面的继承,盒模型相关的属性基本没有继承特性。
1.不可继承的:
display、margin、border、padding、background、height、min-height、max-height、width、min-width、max-width、overflow、position、top、bottom、left、right、z-index、float、clear、 table-layout、vertical-align、page-break-after、page-bread-before和unicode-bidi。
2.所有元素可继承的:
visibility和cursor
3.终极块级元素可继承的:
text-indent和text-align
4.内联元素可继承的:
letter-spacing、word-spacing、white-space、line-height、color、font、font-family、font-size、font-style、font-variant、font-weight、text-decoration、text-transform、direction
5.列表元素可继承的:
list-style、list-style-type、list-style-position、list-style-image

34.什么是同源策略

同源策略就是浏览器阻止从一个域上加载脚本或者操作另外个域上面的文本属性,浏览器的最基本的安全功能

什么情况下会产生跨域:1.域名不同 2.端口不同 3.协议不同 (http端口 :80 https端口:443)

35.如何给元素绑定事件

1.在元素上直接进行绑定事件

2.考点(利用事件绑定)标准浏览器:addeventlistener(‘事件名’,‘回调’,是否捕获) ie:attachevent(‘on事件名’,回调)

--------------移除事件:removeEventListener , Dettachevent

36.什么是闭包,如何使用它,为什么要使用它;

什么是闭包:函数嵌套函数,内部变量,能被外部访问

优点:函数内部变量能被外部访问,内存永驻,有独立的作用域,避免了全局污染

缺点:过多的变量 会造成浏览器的回收机制失效,造成内存泄漏

处理:手动销毁这些变量

37.事件委托;

利用冒泡原理,把事件加到父级上,触发执行效果**
可 以大量节省内存占用,减少事件注册

可以方便地动态添加和修改元素,不需要因为元素的改动而修改事件绑定

缺点:太多的事件委托会造成事件误判

38.常见的ES6语法

let,const,箭头函数,字符串模板,class类,模块化,promise,解构赋值,对象冻结 set,object.assign)

(object.freeze(obj) 冻结对象 冻结后属性无法更改 , 该方法只能冻结对象内的第一层属性,也就是说如果要冻结的对象有属性值为对象,那这个作为属性值的对象是无法进行冻结的 ,处理方法(递归 循环判断属性下面的类型是不是对象 如果是就继续冻结)

39.数组去重

1.建立数组,然后用标记法进行循环 如果存在 则改变这个标记 最后输出没有改变标记的数就行

  1. 利用indexOf 判断这个内容是否在数组里出现过 如果没有出现则加入到新的数组里 还是要用到for循环

3.利用indexOf和filter的索引位置去进行去重

4.利用ofEach 配合对象的属性进行去重 如果obj[value]不存在的话 就给value赋值 然后把这个value加入到新的数组中

5.利用对象的属性重复覆盖的原理 然后利用循环把arr[i]当成属性加入到对象当中 最后输出 object.keys(obj) keys 是对象下面的方法所以前面要加object,括号里跟对象

6.利用set 结构 //数组去重
// let arr=[1,2,3,4,5,6,6,5,4,3,2,1];
// console.log([…new Set(arr)]);//[1, 2, 3, 4, 5, 6]

40.数组排序

冒泡排序:

思路:1.比较相邻两个元素,若前一个比后一个大,则交换位置

2.第一轮结束之后,最后一个元素的值是最大的;

3.接着开始第二轮,但是不用再比较最后一个元素了;

4.第一轮除外,以后的每一轮都比前一轮少比较一次;

var bubbleSort = function (arr){
  var i, j, m;
  var len = arr.length;
  if (len <= 1) {
    return arr;
  }
 
  for (i=0; i<len-1; i++) {
    for (j=0; j<len-i-1; j++) {
      if (arr[j] > arr[j+1]) {
        m = arr[j];
        arr[j] = arr[j+1];
        arr[j+1] = m;
      }
    }
  }
  return arr;
};
**// let arr=[1,2,3,4,5,6,6,5,4,3,2,1];**
**// console.log([...new Set(arr)]);//[1, 2, 3, 4, 5, 6]**	
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值