面试题整理

84 阅读7分钟

css部分

什么是BFC 

"块级格式化上下文"。它是一个独立的渲染区域   

解决的问题:

  • 避免外边距折叠 ----- overflow:hidden
  • 避免文字环绕
  • 包含浮动元素,让浮动元素不会乱跑

如何形成BFC

二、 形成 BFC 的条件

1、浮动元素,float 除 none 以外的值;

2、绝对定位元素,position(absolute,fixed);

3、display 为以下其中之一的值 inline-blocks,table-cells,table-captions;

4、overflow 除了 visible 以外的值(hidden,auto,scroll)。

清除浮动的几种方法

1,在父元素中 最后的位置 添加 一个空的div,并定义 其属性 clear:both。

2 父元素增加 overflow:hidden 属性

3 给父元素定义高度,

什么是盒子模型?

把所有的网页元素都看成一个盒子,它具有: 

content,padding,border,margin 四个属性,这就是盒子模型。

标准盒模型和怪异盒模型 CSS那个属性可以转换他们 box-sizing

在标准模式下,一个块的宽度 = width + padding(左右) + border(左右) + margin(左右)

在怪异模式下,一个块的宽度 = width + margin(左右)

当设置为box-sizing:content-box时,将采用标准模式解析计算,也是默认模式;

当设置为box-sizing:border-box时,将采用怪异模式解析计算

position:sticky 新特性

一般用来做吸顶,但是安卓兼容性不好

css权重的等级

(1)!important,加在样式属性值后,权重值为10000

(2)内联样式,如:style="",权重值为1000

(3)ID选择器,如:#content,权重值为100

(4)类,伪类和属性选择器,如:content、:hover权重值为10

(5)标签选择器和伪元素选择器,如:div,p,:before权重值为1

(6)通用选择器( * ) 、子选择器(>)、相邻选择器(+)、同胞选择器(~)、权重值为0

什么是回流

当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow)。每个页面至少需要一次回流,就是在页面第一次加载的时候,这时候是一定会发生回流的,因为要构建render tree。在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程成为重绘。

什么是重绘

当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。

回流重绘的区别:

回流必将引起重绘,而重绘不一定会引起回流。比如:只有颜色改变的时候就只会发生重绘而不会引起回流

当页面布局和几何属性改变时就需要回流

比如:添加或者删除可见的DOM元素,元素位置改变,元素尺寸改变——边距、填充、边框、宽度和高度,内容改变

js部分

闭包:

一个函数他在它的词法作用域外被调用,能访问到它词法作用域链内的所有变量

一、原型

①所有引用类型(数组,对象,函数)都有一个__proto__(隐式原型)属性,属性值是一个普通的对象

②所有函数都有一个prototype(原型)属性,属性值是一个普通的对象

③所有引用类型的__proto__属性指向它构造函数的prototype

二、原型链

当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的__proto__中查找,这样一层一层向上查找就会形成一个链式结构,我们称为原型链。

new创建新实例对象经过了以下几步:

(1) 在内存中创建一个新对象。

const obj ={}

(2) 这个新对象内部的_proto_指针被赋值为构造函数的 prototype 属性。

obj.constructor = Person

obj._proto_ = Person.protoType

(3) 即 this 指向新对象 (构造函数内部的 this 被赋值为这个新对象()。)

Person.call(obj)

(4) 执行构造函数内部的代码(给新对象添加属性)。返回新对象

判断JS对象属于哪一类

1 typeof

2 instanceOf

3 Object.prototype.toString.call()

prototype从英文就说了是“原型”的意思。就是说你这个Object.prototype.toString调用的是object的原型(也就是父类)的tostring方法。

4 constructor

function A(){};
function B(){};
A.prototype = new B(); 
var aObj = new A();
aObj.constructor === B; //true; 
aObj.constructor === A; //false;

用途:检测实例和类的关系,从而检测数据类型,实例的原型_proto_与类的原型对象指向一样,类的原型对象上有constructor属性指向类本身

reflect存在的意义:

1,从Reflect对象上可以拿到语言内部的方法。将object对象一些内部的方法,放到Reflect对象上。比如:object.defineProperty

说明:现阶段这些方法存在于object和Reflect对象上,未来只存在于Reflect对象上。

2,操作对象时出现报错返回false

说明:比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。

3,让操作对象都变为函数式编程

4,保持和proxy对象的方法一一对象

Event Loop   js运行机制。js是单线程的

1 先执行主线程

2遇到宏任务,放到宏队列

3遇到微任务,放到微队列

4主线程执行完毕

5执行微队列

6 执行宏队列

以此循环

箭头函数和普通函数的区别

  1. 箭头函数是匿名函数,不能作为构造函数,不能使用new
  2. 箭头函数不能绑定arguments,取而代之用rest参数...解决
  3. 箭头函数没有原型属性
  4. 箭头函数的this永远指向其上下文(父级作用域)的this,没有办改变其指向,普通函数的this指向调用它的对象
  5. 箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this值

防抖 节流

//函数防抖

function debounce(func, wait) {

    let timeOut = null;

    return function () {

        clearTimeout(timeOut);

        timeOut = setTimeout(() => {

            func();

        }, wait);

    };

}

//函数节流

function throttle(func,wait){

    let canRun = true;

    return function (){

        if(!canRun){ return }

        canRun = false

        setTimeout(()=>{

            func()

            canRun = true

        },wait)

    }

}

浅拷贝、深拷贝

由于JavaScript中对象是引用类型,保存的是地址,深、浅拷贝的区别是,当拷贝结束后,在一定程度上改变原对象中的某一个引用类型属性的值,新拷贝出来的对象依然受影响的话,就是浅拷贝,反之就是深拷贝。

浅拷贝的几种实现方法

  1. 利用Object.assign()方法
  2. 利用...扩展运算符

深拷贝的实现方法

  1. 配合使用JSON.parse()JSON.stringify()两个函数(局限性比较大) (1). 会忽略属性值为undefined的属性 (2). 会忽略属性为Symbol的属性 (3). 不会序列化函数 (4). 不能解决循环引用的问题,直接报错

  2. lodash第三方库实现深拷贝**

  3. 实现自己的深拷贝方法(解决循环引用问题) //使用Map的key可以是对象的特性。把要拷贝的目标对象,当做Key存起来,value是深拷贝后的对象(在Map中有这样一个键值对)。

function deepCopy(obj, map = new Map()) {
  if (typeof obj === 'object') {
     let res = Array.isArray(obj) ? [] : {};
         if(map.get(obj)){
                return map.get(obj);
         }
         map.set(obj,res);
         for(var i in obj){
           res[i] = deepCopy(obj[i],map);
         }
         return map.get(obj);
  }else{
        return obj;
  }
};
var A={a:1};
A.A=A;

var B = deepCopy(A); console.log(B);//{a: 1, A: {a: 1, A: {…}}

垃圾回收机制-标记清理

垃圾回收程序运行的时候,会标记内存中存储的所有变量(记住,标记方法有很多种)。然后,它 会将所有在上下文中的变量,以及被在上下文中的变量引用的变量的标记去掉。在此之后再被加上标记 的变量就是待删除的了,原因是任何在上下文中的变量都访问不到它们了。随后垃圾回收程序做一次内 存清理,销毁带标记的所有值并收回它们的内存。

什么是内存泄露?

即内存被一直占用,没有释放,可以内存慢慢慢地减少,直到没有内存可用。 导致各种应用运行缓慢,甚至崩溃,操作系统死机等。

虚拟dom的优缺点

截图.png