面试题整理(二)

1.对象方法
2.新建对象时,new操作符干了什么?var a = new A;
3.bem,bfc
4.永久性重定向(301)和临时性重定向(302)对 SEO 有什么影响?
5.一个div,左边固定,右边、自适应,有几种方法?
6.清除浮动
7.div水平垂直居中
8.VUE双向绑定原理,对MVVM的理解
9.diff算法时间复杂度及原理
10.webpack打包时如何优化减少打包时间?webpack loader和plugin有什么区别?
11.尾递归优化,尾调用优化?
12.遇到过哪些兼容性问题?
13.深度优先遍历
14.嵌套数组展开
15.跨域
16.文本溢出显示省略号,一行或多行的情况分别处理
17.Git命令,从指定分支新建分支。
18.找出数组中重复次数最多的元素
19.Linux命令,打印执行过的命令
20.proxy
21.将数字反转,63->36

1.对象方法

答:

  • Object.defineProperty() 修改对象属性的默认特性,创建新属性
  • Object.defineProperties() 多个
  • Object.getOwnPropertyDescriptor() 取得给定属性的描述符
  • instanseOf()检测对象类型
  • a.isPrototypeOf(b) a是否是b的原型
  • Object.getPrototypeOf(a) 找到a的原型
  • hasOwnProperty()返回实例属性
  • in 操作符 存在原型链上的属性
  • hasPrototypeProperty() 返回原型属性
  • Object.keys()返回实例上的可枚举属性
  • Object.getOwnPropertyNames()返回实例上的所有属性,无论是否可枚举

2.新建对象时,new操作符干了什么?var a = new A;

答:这种方式调用构造函数,实际经历了以下4个步骤:
(1)创建一个新对象;
(2)将构造函数的作用域赋给新对象;(因此this就指向了新对象)
(3)执行构造函数中的代码;(为这个新对象添加属性)
(4)返回新对象。

  1. bem,bfc
    瓜子二手车、微店

答:原文链接:https://juejin.im/post/5909db2fda2f60005d2093db

BFC(Block Formatting Context)翻译为块级格式化上下文,它其实就是一个css布局的概念,是一个上下文环境, 是一块区域,是一个隔离的独立容器,容器里的子元素不会影响到外面的元素, 反之亦然。
formatting context 是一个决定如何渲染的容器。

  • BFC布局规则:
    (1)内部的box会在垂直方向一个接一个的放置。
    (2)box之间垂直间距由margin决定,属于同一个BFC的两个相邻的box的margin会重叠。
    (3)每个元素的marginbox的左边与包含块borderbox的左边相接触,即使存在浮动也如此。???
    (4)BFC的区域不会与floatbox重叠。
    (5)BFC就是页面上的一个独立区域,区域里面的子元素布局不会影响到外面的布局排列,反之亦然。
    (6)计算BFC高度时,浮动元素也参与计算。
    (7)位于不同BFC下的元素不会发生margin重叠。

  • BFC有哪些用途?
    (1)自适应两栏布局
    (2)可以阻止元素被浮动元素覆盖,把不浮动的元素添加overflow:hidden ,触发该元素的bfc,让自己免受外界影响。
    (3)可以清除内部浮动(清除浮动的原理是两个div都位于同一个浮动的BFC区域之中。)
    (4)分属于不同的BFC 可以阻止margin重叠。
    (5)解决浮动问题。给父元素加overflow:hidden触发bfc,形成一个独立的渲染区域,所以内部的元素不会影响外面的布局,bfc把浮动子元素的高度算作自己的高度处理溢出,所以外界不会受到影响。

  • 触发BFC有哪些方式?
    (1)根元素HTML
    (2)float不为none
    (3)display为inline-block或table-cell
    (4)overflow不为visible
    (5)position不为static
    (6)flex-boxes
    概括来说就是脱离了文档流的元素

  • 文本环绕?


    image.png

    image.png

    div会被float覆盖而文本不会,这是因为float当初设计的时候就是为了让文本在浮动对象周围。

BEM( Block,Element和Modifier的缩写)是一个高可用的,强大的,而且简单的命名规范,它可以使得你的前端代码更加易读和理解,容易与他人协作,容易扩展,更加强壮和明确,关键是更加严谨

  1. 永久性重定向(301)和临时性重定向(302)对 SEO 有什么影响?
    github 124

答:从SEO角度出发,301优于302。

  • 301:(Permanently Moved),从搜索引擎优化角度来讲, 301是转移网址最好的办法,因为当网站的域名改变后,搜索引擎只对新网址进行搜索,旧网址下的所有外部链接全部转移到新网址下, 旧网址排名清零作废,从而不会让网站的排名受到影响。另外,使用301命令让多个域名指向网站主域时,也不会对网站的排名产生负面影响。
  • 302:(Temporarily Moved ),使用302重定向时, 绝大部分浏览器会把链接成绩向多个域名分摊,因此就会削弱网站主站的链接总量,作为网站排名的关键因素之一的外链数量受到影响,网站排名自然会降低。目前为止, 只有谷歌对302的这个行为进行了优化,当其他域名指向主域时,会把其他域名的链接成绩计入主域。

5.一个div,左边固定,右边、自适应,有几种方法?
博彦科技
bfc、左边position:absolute,右边margin-left、flex、计算属性、table

(1)bfc方法(最优,左边菜单拖拽的情况下,可以监听左边元素的宽度,右边什么值都不用改)

<div class="aside"></div>
<div class="text">
  <div class="main">aaaaa</div>
</div>
.aside {
  width: 100px;
  height: 150px;
  float: left;
  background: #f66;
}

.main {
  height: 200px;
  overflow: hidden;
  background: #fcc;
}

.text {
  width: 100%;
}

注意:是右边部分的父元素宽度100%,让main自己形成一个bfc,bfc的区域不会与float-box重叠。


image.png

(2)左边position:absolute,右边margin-left,这个方式和让左边float-left同理。

<div class="parent">
  <div class="l-child">左边固定1 左边固定2 左边固定3</div>
  <div class="r-child">右边自适应1 右边自适应2 右边自适应3</div>
</div>
.parent {
  display: relative;
  background: #ddd
}

.l-child {
  position: absolute;
  width: 100px;
  background: #bbb
}

.r-child {
  margin-left: 100px;
  background: #999
}
image.png

(3)flex

body{
            display: flex;
        }
.right{
            flex:1
        }

(4)table布局

        body{
            display: table;
            width:100%;
        }
        .left{
            display: table-cell;
        }
        .right{
            display: table-cell;
        }

6.清除浮动
大搜车、微店、
https://juejin.im/post/59e7190bf265da4307025d91

答:clear、父元素前加空标签做clear、在parent上加一个伪类,让这个伪类清除浮动、浮动元素的父元素增加overflow不为visible的属性(BFC)。

(1)在被float影响的元素上添加clear:both;
如下图,浮动元素导致text元素和下面的other被遮挡。父元素高度撑不开。


image.png

解决办法:


image.png

不过这种办法也有漏洞,假如浮动元素在text后面,父元素高度依然撑不开,other依然会被影响。
(2)父元素结束标签之前插入清除浮动的块级元素
原理同上。
image.png

(3)在parent上加一个伪元素,让这个伪元素清除浮动,原理和上面两种相同。


image.png

(4)浮动元素的父元素增加overflow不为visible的属性,原理是,这样会触发BFC,而BFC高度包含浮动元素。
image.png

7.div水平垂直居中
作业帮、大搜车、

答:

  • 未知父元素,未知子元素宽高
    (1) flex
.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

(2)table cell
子元素设置为inline或inline-block时,父元素display:table-cell

.parent {
  border: 1px solid black;
  display: table-cell;
  width: 500px;
  height: 500px;
  vertical-align: middle;
  text-align: center;
}

.child {
  width: 100px;
  height: 100px;
  border: 1px solid red;
  display: inline-block;

}

(3)绝对定位+子元素transform:translate(-50%,-50%);

.parent {
  border: 1px solid black;
  width: 500px;
  height: 500px;
  position: relative;
}

.child {
  width: 100px;
  height: 100px;
  border: 1px solid red;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
  • 已知子元素宽高,未知父元素宽高
    (1)子元素绝对定位,top和left都设为50%,然后margin-top和margin-left设为负数自身的一半。
.parent {
  width: 500px;
  height: 500px;
  border: 1px solid black;
  position: relative;
}

.child {
  height: 100px;
  width: 100px;
  border: 1px solid red;
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -50px 0 0 -50px;
}

(2)子元素绝对定位,top,bottom,right,left值均为0,margin设为auto。

.parent {
  border: 1px solid black;
  position: relative;
}

.child {
  width: 100px;
  height: 100px;
  border: 1px solid red;
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  margin: auto;
}

8.VUE双向绑定原理,对MVVM的理解
酷家乐,博彦科技

答:VUE双向绑定是通过Object.defineProperty的数据劫持能力,结合发布者订阅者模式实现的。
vue中的data实际上是一个带有访问器属性(getter和setter)的对象。

什么是访问器属性?
JS对象有两种属性:数据属性和访问器属性,访问器属性不能直接定义,必须通过Object.defineProperty()来定义,它包含一对getter,setter函数,在读取访问器属性时,会调用getter,在写入访问器属性时,会调用setter 并传入新值。setter这个函数负责如何处理数据。

VUE 就是通过这个Object.defineProperty来实现数据劫持的。

VUE 的双向绑定包括两个方面,view更新data,data更新view。
view更新data比较简单,通过事件监听即可,比如input标签绑定input事件。

比较困难的是data更新view。
这里面有两个点:
1.如何知道数据变了?
2.数据变了如何更新DOM?

对以上两点做出一些解答:
1.如何知道数据变了?
其实上面已经给出答案了,就是通过Object.defineProperty()对属性设置一个set函数,数据改变时就会触发这个函数,我们将一些更新view的方法放在set函数的逻辑里,就可以实现data更新view了。


image.png
实现过程

(1)实现数据的双向绑定,首先要对数据进行劫持监听,所以第一步需要设置一个监听器Observer,用来监听所有属性。
(2)如果属性发生变化了,就要告诉订阅者watcher看是否需要更新。
(3)因为订阅者watcher有很多个,所以需要一个消息订阅器Dep来专门收集这些订阅者,在监听器Observer和订阅器Watcher之间进行统一管理。
(4)接着,为了解析view上的指令, 我们需要一个指令解析器Compiler,对页面每个节点和元素进行扫描和解析,将相关指令初始化成一个订阅者watcher。通过解析指令绑定相应的函数。
(5)此时,当watcher收到来自Observer的通知,就会执行对应的更新view的函数。

image.png
如果要自己实现一个双向绑定也就大致需要以下三个步骤:

1.实现一个监听器Observer,用来劫持监听所有的属性,有变动就通知watcher。
2.实现一个watcher,可以收到监听器传来的属性变化通知,并执行相应的函数,从而更新视图。
3.实现一个解析器Compile,可以扫描解析每个节点的指令,并初始化末班数据和初始化订阅器。

以下详细思考每个步骤如何实现?

1.实现Observer

Observer是一个数据监听器,其实现的核心方法就是前文所说的Object.defineProperty(),如果要对所有的属性都进行监听的话,可以用递归的方法遍历所有属性值,对其进行Object.defineProperty处理。

image.png

还需要创建一个容纳所有Watcher的订阅器Dep,订阅器主要负责收集订阅者,然后属性变化的时候,执行对应订阅者的更新函数,所以显然订阅者需要有一个容器,这个容器就是list,将上面的代码稍微改造下,植入Dep。


image.png

在get里面添加一个订阅器是为了初始化触发,所以初始化时要判断是否需要添加watcher,这个要具体情况具体考虑。
接下来实现watcher.

2.实现监听器watcher

9.diff 算法时间复杂度及原理
大搜车、作业帮
https://user-gold-cdn.xitu.io/2019/8/1/16c49afec13e0416

10.webpack打包时如何优化减少打包时间?webpack loader和plugin有什么区别?
北明软件、瓜子二手车、博彦科技、滴滴

11.尾递归优化,尾调用优化?
https://www.jianshu.com/p/0ed8ed003fe0

12.遇到过哪些兼容性问题?

答:

  • js
    (1)DOM2级定义的深度优先遍历器NodeIterator 和 TreeWalker在IE中没有对应的类型和方法,所以使用遍历的跨浏览器解决方案非常少见。
  • css

13.深度优先遍历

  • 递归
function deepTraversal(node,nodeList) {  
    if (node) {    
            nodeList.push(node);    
            var children = node.children;    
            for (var i = 0; i < children.length; i++) 
                deepTraversal(children[i],nodeList);    
        }    
    return nodeList;  
}  
var root = document.getElementById('root')
console.log(deepTraversal(root,nodeList=[]))
  • 非递归
function deepTraversal(node) {  
    var nodeList = [];  
    if (node) {  
        var stack = [];  
        stack.push(node);  
        while (stack.length != 0) {  
            var childrenItem = stack.pop();  
            nodeList.push(childrenItem);  
            var childrenList = childrenItem.children;  
            for (var i = childrenList.length - 1; i >= 0; i--)  
                stack.push(childrenList[i]);  
        }  
    }    
    return nodeList;  
}   
var root = document.getElementById('root')
console.log(deepTraversal(root))
  1. 嵌套数组展开
  • 递归
function flattenMd(arr) {
    var result = [];
    for(var i = 0; i < arr.length; i++){
        if(arr[i] instanceof Array) {
            result = result.concat(flattenMd(arr[i]));
        }
        else {
            result.push(arr[i]);
        }
    }
    return result;
}
var arr=[1, [2, 3, [4, 5], 6], 7, 8]
console.log(flattenMd(arr));
  • 非递归
function flattenDeep(arr){
    const res = [];
    const stack = [...arr];
    while(stack.length){
        let item = stack.shift();
        Array.isArray(item)?stack.unshift(...item):res.push(item);
    }
    return res;
}
var arr = [1,[2,[3,[[5]]],[4]]];
console.log(flattenDeep(arr))

15.跨域解决办法?同源策略是什么?
博彦科技,大搜车,酷家乐,滴滴,贝壳

答: 通过XHR实现ajax的一个主要限制就来源于跨域安全策略。
默认情况下,XHR对象只能访问与包含它的页面位于同一个域中的资源。
以下简要说明常用方法:

  • CORS
  • IE和其他浏览器对CORS的实现
  • Preflighted Request
  • withCredentials 带凭据的请求
  • 跨浏览器的CORS

CORS(Cross-Origin Resource Sharing)

CORS背后的思想是,使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应应该是成功还是失败。

CORS的使用方法:
在发送请求时,需要给它附加一个额外的Origin头部,其中包含请求页面的信息(协议,域名,端口),以便服务器根据这个信息决定是否给予响应。

Origin: http://www.nczonline.net

如果服务器认为这个请求可以接受,就在Access-Control-Allow-Origin头部中回发相同的源信息。

Access-Control-Allow-Origin:http://www.nczonline.net

如果没有这个头部,或者有这个头部但是源信息不匹配,浏览器就会驳回请求,正常情况下,浏览器会处理请求。
请求和响应都不包含cookie信息。

IE对CORS 的实现:

微软在IE8中引入了XDR(XDomainRequest)类型,与XHR相似,但是能实现跨域通信。
XDR使用方法和XHR类似,
(1)创建一个XDomainRequest对象
(2)open() //与XHR不同的是XDR只接受两个参数,请求类型和URL
(3)send()

缺点:
(1)所有的XDR都是异步的,不能用来创建同步请求。
(2)收到响应后,只能访问响应的原始文本,没有办法确定响应的状态码。成功触发onload,响应数组放在xhr.responseText中,失败触发onerror,但是除了错误本身之外,没有其他信息可以用。

XDR也支持
onerror()检测错误
abort()在请求返回前终止请求
timeout属性 超时设定
ontimeout()事件处理程序 超时处理程序

其他浏览器对CORS的实现

Firefox3.5+,Sarafi4+,Chrome,ios版Safari和Android平台中的webkit都通过XHR对象实现了对CORS的原生支持。

使用方法:

要请求另一个域中的资源,使用标准的XHR对象,并在open()方法中传入绝对的URL即可。

对比IE中XDR的优点:
(1)XHR可以访问status和statusText属性
(2)可以发送同步请求

但是出于安全考虑也有一些限制:
(1)不能使用setRequestHeader自定义头部信息。
(2)不能发送接收cookie
(3)调用getAllResponseHeaders()总是返回空字符串。

因为同源请求和跨域请求使用相同的接口,所以建议本地资源使用相对URL,远程资源使用绝对URL,这样能消除歧义,避免出现 限制访问头部或本地cookie信息等问题。

Preflighted Request

支持Preflight请求的浏览器有Firefox3.5+,Safari4+,Chrome

CORS 通过Preflighted Request的透明服务器验证机制支持开发人员使用自定义的GET或POST之外的方法,以及不同类型的主题内容。浏览器向服务器通过高级选项发送一个Preflight请求,服务器可以决定是否允许这种类型的请求。

withCredentials 带凭据的请求

支持withCredentials的浏览器有Firefox3.5+,Safari4+,Chrome,IE10及更早版本都不支持。

默认情况下,跨源请求不提供凭据,(cookie,HTTP认证及客户端SSL等),
通过将withCredentials设置为true,可以指定某个请求应该发送凭证。如果服务器接收带凭据的请求,会用下面的HTTP头部来响应。
Access-Control-Allow-Credentials: true

16.文本溢出显示省略号,一行或多行的情况?

答:

  • 一行:
 overflow: hidden;
  text-overflow: ellipsis;
  white-space:nowrap;
}
  • 多行
.a {
  display: inline-block;
  width: 200px;
  height: 200px;
  overflow: hidden;
  position: relative;
}

.a::after {
  content: '...';
  position: absolute;
  right: 0;
  bottom: 0;
}

17.Git命令,从指定分支新建分支。

git branch [branch name] [from branch name ]

18.找出数组中重复次数最多的元素

答:

var arr = [1];
var res = {};
var most = -1;
var ele = -1;

function findMost(arr) {
  if (!arr.length) {
    return
  } else if (arr.length == 1) {
    return arr[0];
  } else if (arr.length > 1) {
    for (let i = 0; i < arr.length; i++) {
      res[arr[i]] ? res[arr[i]]++ : res[arr[i]] = 1;
      if (res[arr[i]] > most) {
        most = res[arr[i]];
        ele = arr[i];
      }

    }
  }
  console.log(ele);

}

findMost(arr);

19.Linux命令,打印执行过的命令

history [n] //n是数字,要打印的条数

20.proxy
VUE3.0的双向数据绑定

proxy用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”,即对 编程语言进行编程。
Proxy可以理解成在目标对象前架设一个拦截层,外界对该对象的访问必须先通过这层拦截,因此提供了一种机制可以对外界的访问进行过滤和改写。Proxy这个词的愿意是代理,用在这里表示由他来”代理“某些操作,可以译为代理器

21.将数字反转

答:

function reverseNum(n){
console.log(n.toString().split("").reverse().join("")) | 0;
}
reverseNum(123);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,175评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,674评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,151评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,597评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,505评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,969评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,455评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,118评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,227评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,213评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,214评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,928评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,512评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,616评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,848评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,228评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,772评论 2 339

推荐阅读更多精彩内容

  • 一、理论基础知识部分 1.1、讲讲输入完网址按下回车,到看到网页这个过程中发生了什么 a. 域名解析 b. 发起T...
    我家媳妇蠢蠢哒阅读 3,106评论 2 106
  • 设计模式是什么? 你知道哪些设计模式,并简要叙述? 设计模式是一种编码经验,就是用比较成熟的逻辑去处理某一种类型的...
    Jt_Self阅读 724评论 0 4
  • 41.+load和+initialize区别是什么? Apple的文档很清楚地说明了initialize和load...
    Lessin阅读 944评论 0 4
  • 【转载】CSDN - 张林blog http://blog.csdn.net/XIAOZHUXMEN/articl...
    竿牍阅读 3,475评论 1 14
  • 接上文Android面试题整理(一) 21.数据的存储方式 File 存储 SharedPreference 存储...
    大弃阅读 770评论 0 7