关于前端:京东前端一面高频面试题附答案

40次阅读

共计 10943 个字符,预计需要花费 28 分钟才能阅读完成。

左右居中计划

  • 行内元素: text-align: center
  • 定宽块状元素: 左右 margin 值为 auto
  • 不定宽块状元素: table布局,position + transform
/* 计划 1 */
.wrap {text-align: center}
.center {
  display: inline;
  /* or */
  /* display: inline-block; */
}
/* 计划 2 */
.center {
  width: 100px;
  margin: 0 auto;
}
/* 计划 2 */
.wrap {position: relative;}
.center {
  position: absulote;
  left: 50%;
  transform: translateX(-50%);
}

—- 问题知识点分割线 —-

代码输入后果

function Person(name) {this.name = name}
var p2 = new Person('king');
console.log(p2.__proto__) //Person.prototype
console.log(p2.__proto__.__proto__) //Object.prototype
console.log(p2.__proto__.__proto__.__proto__) // null
console.log(p2.__proto__.__proto__.__proto__.__proto__)//null 前面没有了,报错
console.log(p2.__proto__.__proto__.__proto__.__proto__.__proto__)//null 前面没有了,报错
console.log(p2.constructor)//Person
console.log(p2.prototype)//undefined p2 是实例,没有 prototype 属性
console.log(Person.constructor)//Function 一个空函数
console.log(Person.prototype)// 打印出 Person.prototype 这个对象里所有的办法和属性
console.log(Person.prototype.constructor)//Person
console.log(Person.prototype.__proto__)// Object.prototype
console.log(Person.__proto__) //Function.prototype
console.log(Function.prototype.__proto__)//Object.prototype
console.log(Function.__proto__)//Function.prototype
console.log(Object.__proto__)//Function.prototype
console.log(Object.prototype.__proto__)//null

这道义题目考查原型、原型链的根底,记住就能够了。

—- 问题知识点分割线 —-

介绍一下 webpack scope hosting

作用域晋升,将扩散的模块划分到同一个作用域中,防止了代码的反复引入,无效缩小打包后的代码体积和运行时的内存损耗;

—- 问题知识点分割线 —-

原型

JavaScript 中的对象都有一个非凡的 prototype 内置属性,其实就是对其余对象的援用
简直所有的对象在创立时 prototype 属性都会被赋予一个非空的值,咱们能够把这个属性当作一个备用的仓库
当试图援用对象的属性时会登程 get 操作,第一步时查看对象自身是否有这个属性,如果有就应用它,没有就去原型中查找。一层层向上直到 Object.prototype 顶层

基于原型扩大形容一下原型链,什么是原型链,原型的继承,ES5 和 ES6 继承与不同点。

—- 问题知识点分割线 —-

display 的 block、inline 和 inline-block 的区别

(1)block: 会独占一行,多个元素会另起一行,能够设置 width、height、margin 和 padding 属性;

(2)inline: 元素不会独占一行,设置 width、height 属性有效。但能够设置程度方向的 margin 和 padding 属性,不能设置垂直方向的 padding 和 margin;

(3)inline-block: 将对象设置为 inline 对象,但对象的内容作为 block 对象出现,之后的内联对象会被排列在同一行内。

对于行内元素和块级元素,其特点如下:

(1)行内元素

  • 设置宽高有效;
  • 能够设置程度方向的 margin 和 padding 属性,不能设置垂直方向的 padding 和 margin;
  • 不会主动换行;

(2)块级元素

  • 能够设置宽高;
  • 设置 margin 和 padding 都无效;
  • 能够主动换行;
  • 多个块状,默认排列从上到下。

—- 问题知识点分割线 —-

为什么 React 元素有一个 $$typeof 属性

目标是为了避免 XSS 攻打。因为 Synbol 无奈被序列化,所以 React 能够通过有没有 $$typeof 属性来断出以后的 element 对象是从数据库来的还是本人生成的。

  • 如果没有 $$typeof 这个属性,react 会回绝解决该元素。
  • 在 React 的古老版本中,上面的写法会呈现 XSS 攻打:
// 服务端容许用户存储 JSON
let expectedTextButGotJSON = {
  type: 'div',
  props: {
    dangerouslySetInnerHTML: {__html: '/* 把你想的搁着 */'},
  },
  // ...
};
let message = {text: expectedTextButGotJSON};

// React 0.13 中有危险
<p>
  {message.text}
</p>

—- 问题知识点分割线 —-

懒加载与预加载的区别

这两种形式都是进步网页性能的形式,两者次要区别是一个是提前加载,一个是缓慢甚至不加载。懒加载对服务器前端有肯定的缓解压力作用,预加载则会减少服务器前端压力。

  • 懒加载也叫提早加载,指的是在长网页中提早加载图片的机会,当用户须要拜访时,再去加载,这样能够进步网站的首屏加载速度,晋升用户的体验,并且能够缩小服务器的压力。它实用于图片很多,页面很长的电商网站的场景。懒加载的实现原理是,将页面上的图片的 src 属性设置为空字符串,将图片的实在门路保留在一个自定义属性中,当页面滚动的时候,进行判断,如果图片进入页面可视区域内,则从自定义属性中取出实在门路赋值给图片的 src 属性,以此来实现图片的提早加载。
  • 预加载指的是将所需的资源提前申请加载到本地,这样前面在须要用到时就间接从缓存取资源。 通过预加载可能缩小用户的等待时间,进步用户的体验。我理解的预加载的最罕用的形式是应用 js 中的 image 对象,通过为 image 对象来设置 scr 属性,来实现图片的预加载。

—- 问题知识点分割线 —-

对类数组对象的了解,如何转化为数组

一个领有 length 属性和若干索引属性的对象就能够被称为类数组对象,类数组对象和数组相似,然而不能调用数组的办法。常见的类数组对象有 arguments 和 DOM 办法的返回后果,函数参数也能够被看作是类数组对象,因为它含有 length 属性值,代表可接管的参数个数。

常见的类数组转换为数组的办法有这样几种:

  • 通过 call 调用数组的 slice 办法来实现转换
Array.prototype.slice.call(arrayLike);
  • 通过 call 调用数组的 splice 办法来实现转换
Array.prototype.splice.call(arrayLike, 0);
  • 通过 apply 调用数组的 concat 办法来实现转换
Array.prototype.concat.apply([], arrayLike);
  • 通过 Array.from 办法来实现转换
Array.from(arrayLike);

—- 问题知识点分割线 —-

CSS3 的新个性

  • transition:过渡
  • transform: 旋转、缩放、挪动或歪斜
  • animation: 动画
  • gradient: 突变
  • box-shadow: 暗影
  • border-radius: 圆角
  • word-break: normal|break-all|keep-all; 文字换行(默认规定 | 单词也能够换行 | 只在半角空格或连字符换行)
  • text-overflow: 文字超出局部解决
  • text-shadow: 程度暗影,垂直暗影,含糊的间隔,以及暗影的色彩。
  • box-sizing: content-box|border-box 盒模型
  • 媒体查问 @media screen and (max-width: 960px) {}还有打印print

—- 问题知识点分割线 —-

Ajax

它是一种异步通信的办法,通过间接由 js 脚本向服务器发动 http 通信,而后依据服务器返回的数据,更新网页的相应局部,而不必刷新整个页面的一种办法。

面试手写(原生):

//1:创立 Ajax 对象
var xhr = window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject('Microsoft.XMLHTTP');// 兼容 IE6 及以下版本
//2:配置 Ajax 申请地址
xhr.open('get','index.xml',true);
//3:发送申请
xhr.send(null); // 谨严写法
//4: 监听申请,承受响应
xhr.onreadysatechange=function(){if(xhr.readySate==4&&xhr.status==200 || xhr.status==304)
          console.log(xhr.responsetXML)
}

jQuery 写法

$.ajax({
  type:'post',
  url:'',
  async:ture,//async 异步  sync  同步
  data:data,// 针对 post 申请
  dataType:'jsonp',
  success:function (msg) { },
  error:function (error) {}})

promise 封装实现:

// promise 封装实现:function getJSON(url) {
  // 创立一个 promise 对象
  let promise = new Promise(function(resolve, reject) {let xhr = new XMLHttpRequest();

    // 新建一个 http 申请
    xhr.open("GET", url, true);

    // 设置状态的监听函数
    xhr.onreadystatechange = function() {if (this.readyState !== 4) return;

      // 当申请胜利或失败时,扭转 promise 的状态
      if (this.status === 200) {resolve(this.response);
      } else {reject(new Error(this.statusText));
      }
    };

    // 设置谬误监听函数
    xhr.onerror = function() {reject(new Error(this.statusText));
    };

    // 设置响应的数据类型
    xhr.responseType = "json";

    // 设置申请头信息
    xhr.setRequestHeader("Accept", "application/json");

    // 发送 http 申请
    xhr.send(null);
  });

  return promise;
}

—- 问题知识点分割线 —-

VDOM:三个 part

  • 虚构节点类,将实在 DOM节点用 js 对象的模式进行展现,并提供 render 办法,将虚构节点渲染成实在 DOM
  • 节点 diff 比拟:对虚构节点进行 js 层面的计算,并将不同的操作都记录到 patch 对象
  • re-render:解析 patch 对象,进行 re-render

补充 1��VDOM 的必要性?

  • 创立实在 DOM 的代价高:实在的 DOM 节点 node 实现的属性很多,而 vnode 仅仅实现一些必要的属性,相比起来,创立一个 vnode 的老本比拟低。
  • 触发屡次浏览器重绘及回流:应用 vnode,相当于加了一个缓冲,让一次数据变动所带来的所有 node 变动,先在 vnode 中进行批改,而后 diff 之后对所有产生差别的节点集中一次对 DOM tree 进行批改,以缩小浏览器的重绘及回流。

补充 2:vue 为什么采纳 vdom?

引入 Virtual DOM 在性能方面的考量仅仅是一方面。

  • 性能受场景的影响是十分大的,不同的场景可能造成不同实现计划之间成倍的性能差距,所以依赖细粒度绑定及 Virtual DOM 哪个的性能更好还真不是一个容易下定论的问题。
  • Vue 之所以引入了 Virtual DOM,更重要的起因是为理解耦 HTML依赖,这带来两个十分重要的益处是:
  • 不再依赖 HTML 解析器进行模版解析,能够进行更多的 AOT 工作进步运行时效率:通过模版 AOT 编译,Vue 的运行时体积能够进一步压缩,运行时效率能够进一步晋升;
  • 能够渲染到 DOM 以外的平台,实现 SSR、同构渲染这些高级个性,Weex等框架利用的就是这一个性。

综上,Virtual DOM 在性能上的收益并不是最次要的,更重要的是它使得 Vue 具备了古代框架应有的高级个性。

—- 问题知识点分割线 —-

SSL 连贯断开后如何复原

一共有两种办法来复原断开的 SSL 连贯,一种是应用 session ID,一种是 session ticket。

通过 session ID

应用 session ID 的形式,每一次的会话都有一个编号,当对话中断后,下一次从新连贯时,只有客户端给出这个编号,服务器如果有这个编号的记录,那么单方就能够持续应用以前的秘钥,而不必从新生成一把。目前所有的浏览器都反对这一种办法。然而这种办法有一个毛病是,session ID 只可能存在一台服务器上,如果咱们的申请通过负载平衡被转移到了其余的服务器上,那么就无奈复原对话。

通过 session ticket

另一种形式是 session ticket 的形式,session ticket 是服务器在上一次对话中发送给客户的,这个 ticket 是加密的,只有服务器可能解密,外面蕴含了本次会话的信息,比方对话秘钥和加密办法等。这样不论咱们的申请是否转移到其余的服务器上,当服务器将 ticket 解密当前,就可能获取上次对话的信息,就不必从新生成对话秘钥了。

—- 问题知识点分割线 —-

async/await

Generator 函数的语法糖。有更好的语义、更好的适用性、返回值是 Promise

  • await 和 promise 一样,更多的是考口试题,当然偶然也会问到和 promise 的一些区别。
  • await 相比间接应用 Promise 来说,劣势在于解决 then 的调用链,可能更清晰精确的写出代码。毛病在于滥用 await 可能会导致性能问题,因为 await 会阻塞代码,兴许之后的异步代码并不依赖于前者,但依然须要期待前者实现,导致代码失去了并发性,此时更应该应用 Promise.all。
  • 一个函数如果加上 async,那么该函数就会返回一个 Promise
  • async => *
  • await => yield
// 根本用法

async function timeout (ms) {await new Promise((resolve) => {setTimeout(resolve, ms)    
  })
}
async function asyncConsole (value, ms) {await timeout(ms)
  console.log(value)
}
asyncConsole('hello async and await', 1000)

上面来看一个应用 await 的代码。

var a = 0
var b = async () => {
  a = a + await 10
  console.log('2', a) // -> '2' 10
  a = (await 10) + a
  console.log('3', a) // -> '3' 20
}
b()
a++
console.log('1', a) // -> '1' 1
  • 首先函数b 先执行,在执行到 await 10 之前变量 a 还是 0,因为在 await 外部实现了 generatorsgenerators 会保留堆栈中货色,所以这时候 a = 0 被保留了下来
  • 因为 await 是异步操作,遇到 await 就会立刻返回一个 pending 状态的 Promise 对象,临时返回执行代码的控制权,使得函数外的代码得以继续执行,所以会先执行 console.log('1', a)
  • 这时候同步代码执行结束,开始执行异步代码,将保留下来的值拿进去应用,这时候 a = 10
  • 而后前面就是惯例执行代码了

优缺点:

async/await的劣势在于解决 then 的调用链,可能更清晰精确的写出代码,并且也能优雅地解决回调天堂问题。当然也存在一些毛病,因为 await 将异步代码革新成了同步代码,如果多个异步代码没有依赖性却应用了 await 会导致性能上的升高。

async 原理

async/await语法糖就是应用 Generator 函数 + 主动执行器来运作的

// 定义了一个 promise,用来模仿异步申请,作用是传入参数 ++
function getNum(num){return new Promise((resolve, reject) => {setTimeout(() => {resolve(num+1)
        }, 1000)
    })
}

// 主动执行器,如果一个 Generator 函数没有执行完,则递归调用
function asyncFun(func){var gen = func();

  function next(data){var result = gen.next(data);
    if (result.done) return result.value;
    result.value.then(function(data){next(data);
    });
  }

  next();}

// 所须要执行的 Generator 函数,外部的数据在执行实现一步的 promise 之后,再调用下一步
var func = function* (){var f1 = yield getNum(1);
  var f2 = yield getNum(f1);
  console.log(f2) ;
};
asyncFun(func);
  • 在执行的过程中,判断一个函数的 promise 是否实现,如果曾经实现,将后果传入下一个函数,持续反复此步骤
  • 每一个 next() 办法返回值的 value 属性为一个 Promise 对象,所以咱们为其增加 then 办法,在 then 办法外面接着运行 next 办法挪移遍历器指针,直到 Generator函数运行实现

—- 问题知识点分割线 —-

短轮询、长轮询和 WebSocket 间的区别

1. 短轮询

短轮询的基本思路:

  • 浏览器每隔一段时间向浏览器发送 http 申请,服务器端在收到申请后,不管是否有数据更新,都间接进行 响应。
  • 这种形式实现的即时通信,实质上还是浏览器发送申请,服务器承受申请的一个过程,通过让客户端一直的进行申请,使得客户端可能模仿实时地收到服务器端的数据的变动。

优缺点👇

  • 长处是比较简单,易于了解。
  • 毛病是这种形式因为须要一直的建设 http 连贯,重大节约了服务器端和客户端的资源。当用户减少时,服务器端的压力就会变大,这是很不合理的。

2. 长轮询

长轮询的基本思路:

  • 首先由客户端向服务器发动申请,当服务器收到客户端发来的申请后,服务器端不会间接进行响应,而是先将 这个申请挂起,而后判断服务器端数据是否有更新。
  • 如果有更新,则进行响应,如果始终没有数据,则达到肯定的工夫限度才返回。客户端 JavaScript 响应处理函数会在解决完服务器返回的信息后,再次发出请求,从新建设连贯。

优缺点👇

  • 长轮询和短轮询比起来,它的长处是 显著缩小了很多不必要的 http 申请次数,相比之下节约了资源。
  • 长轮询的毛病在于,连贯挂起也会导致资源的节约

3. WebSocket

  • WebSocket 是 Html5 定义的一个新协定,与传统的 http 协定不同,该协定容许由服务器被动的向客户端推送信息。
  • 应用 WebSocket 协定的毛病是在服务器端的配置比较复杂。WebSocket 是一个全双工的协定,也就是通信单方是平等的,能够互相发送音讯。

—- 问题知识点分割线 —-

代码输入后果

function SuperType(){this.property = true;}

SuperType.prototype.getSuperValue = function(){return this.property;};

function SubType(){this.subproperty = false;}

SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function (){return this.subproperty;};

var instance = new SubType();
console.log(instance.getSuperValue());

输入后果:true

实际上,这段代码就是在实现原型链继承,SubType 继承了 SuperType,实质是重写了 SubType 的原型对象,代之以一个新类型的实例。SubType 的原型被重写了,所以 instance.constructor 指向的是 SuperType。具体如下:

—- 问题知识点分割线 —-

JavaScript 有哪些内置对象

全局的对象(global objects)或称规范内置对象,不要和 “ 全局对象(global object)” 混同。这里说的全局的对象是说在
全局作用域里的对象。全局作用域中的其余对象能够由用户的脚本创立或由宿主程序提供。

规范内置对象的分类:

(1)值属性,这些全局属性返回一个简略值,这些值没有本人的属性和办法。例如 Infinity、NaN、undefined、null 字面量

(2)函数属性,全局函数能够间接调用,不须要在调用时指定所属对象,执行完结后会将后果间接返回给调用者。例如 eval()、parseFloat()、parseInt() 等

(3)根本对象,根本对象是定义或应用其余对象的根底。根本对象包含个别对象、函数对象和谬误对象。例如 Object、Function、Boolean、Symbol、Error 等

(4)数字和日期对象,用来示意数字、日期和执行数学计算的对象。例如 Number、Math、Date

(5)字符串,用来示意和操作字符串的对象。例如 String、RegExp

(6)可索引的汇合对象,这些对象示意依照索引值来排序的数据汇合,包含数组和类型数组,以及类数组构造的对象。例如 Array

(7)应用键的汇合对象,这些汇合对象在存储数据时会应用到键,反对依照插入程序来迭代元素。
例如 Map、Set、WeakMap、WeakSet

(8)矢量汇合,SIMD 矢量汇合中的数据会被组织为一个数据序列。
例如 SIMD 等

(9)结构化数据,这些对象用来示意和操作结构化的缓冲区数据,或应用 JSON 编码的数据。例如 JSON 等

(10)管制形象对象
例如 Promise、Generator 等

(11)反射。例如 Reflect、Proxy

(12)国际化,为了反对多语言解决而退出 ECMAScript 的对象。例如 Intl、Intl.Collator 等

(13)WebAssembly

(14)其余。例如 arguments

总结: js 中的内置对象次要指的是在程序执行前存在全局作用域里的由 js 定义的一些全局值属性、函数和用来实例化其余对象的构造函数对象。个别常常用到的如全局变量值 NaN、undefined,全局函数如 parseInt()、parseFloat() 用来实例化对象的构造函数如 Date、Object 等,还有提供数学计算的单体内置对象如 Math 对象。

—- 问题知识点分割线 —-

箭头函数和一般函数有啥区别?箭头函数能当构造函数吗?

  • 一般函数通过 function 关键字定义,this 无奈联合词法作用域应用,在运行时绑定,只取决于函数的调用形式,在哪里被调用,调用地位。(取决于调用者,和是否独立运行)
  • 箭头函数应用被称为“胖箭头”的操作 => 定义,箭头函数不利用一般函数 this 绑定的四种规定,而是依据外层(函数或全局)的作用域来决定 this,且箭头函数的绑定无奈被批改(new 也不行)。

    • 箭头函数罕用于回调函数中,包含事件处理器或定时器
    • 箭头函数和 var self = this,都试图取代传统的 this 运行机制,将 this 的绑定拉回到词法作用域
    • 没有原型、没有 this、没有 super,没有 arguments,没有 new.target
    • 不能通过 new 关键字调用

      • 一个函数外部有两个办法:[[Call]] 和 [[Construct]],在通过 new 进行函数调用时,会执行 [[construct]] 办法,创立一个实例对象,而后再执行这个函数体,将函数的 this 绑定在这个实例对象上
      • 当间接调用时,执行 [[Call]] 办法,间接执行函数体
      • 箭头函数没有 [[Construct]] 办法,不能被用作结构函数调用,当应用 new 进行函数调用时会报错。
function foo() {return (a) => {console.log(this.a);
  }
}

var obj1 = {a: 2}

var obj2 = {a: 3}

var bar = foo.call(obj1);
bar.call(obj2);

—- 问题知识点分割线 —-

HTTPS 通信(握手)过程

HTTPS 的通信过程如下:

  1. 客户端向服务器发动申请,申请中蕴含应用的协定版本号、生成的一个随机数、以及客户端反对的加密办法。
  2. 服务器端接管到申请后,确认单方应用的加密办法、并给出服务器的证书、以及一个服务器生成的随机数。
  3. 客户端确认服务器证书无效后,生成一个新的随机数,并应用数字证书中的公钥,加密这个随机数,而后发给服 务器。并且还会提供一个后面所有内容的 hash 的值,用来供服务器测验。
  4. 服务器应用本人的私钥,来解密客户端发送过去的随机数。并提供后面所有内容的 hash 值来供客户端测验。
  5. 客户端和服务器端依据约定的加密办法应用后面的三个随机数,生成对话秘钥,当前的对话过程都应用这个秘钥来加密信息。

—- 问题知识点分割线 —-

迭代查问与递归查问

实际上,DNS 解析是一个蕴含迭代查问和递归查问的过程。

  • 递归查问 指的是查问申请收回后,域名服务器代为向下一级域名服务器发出请求,最初向用户返回查问的最终后果。应用递归 查问,用户只须要收回一次查问申请。
  • 迭代查问 指的是查问申请后,域名服务器返回单次查问的后果。下一级的查问由用户本人申请。应用迭代查问,用户须要收回 屡次的查问申请。

个别咱们向本地 DNS 服务器发送申请的形式就是递归查问,因为咱们只须要收回一次申请,而后本地 DNS 服务器返回给我 们最终的申请后果。而本地 DNS 服务器向其余域名服务器申请的过程是迭代查问的过程,因为每一次域名服务器只返回单次 查问的后果,下一级的查问由本地 DNS 服务器本人进行。

正文完
 0