关于javascript:那些高级前端是如何回答面试题的

27次阅读

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

TCP 和 UDP 的区别

UDP TCP
是否连贯 无连贯 面向连贯
是否牢靠 不牢靠传输,不应用流量管制和拥塞管制 牢靠传输(数据程序和正确性),应用流量管制和拥塞管制
连贯对象个数 反对一对一,一对多,多对一和多对多交互通信 只能是一对一通信
传输方式 面向报文 面向字节流
首部开销 首部开销小,仅 8 字节 首部最小 20 字节,最大 60 字节
实用场景 实用于实时利用,例如视频会议、直播 实用于要求牢靠传输的利用,例如文件传输

CSS 中可继承与不可继承属性有哪些

一、无继承性的属性

  1. display:规定元素应该生成的框的类型
  2. 文本属性
  3. vertical-align:垂直文本对齐
  4. text-decoration:规定增加到文本的装璜
  5. text-shadow:文本暗影成果
  6. white-space:空白符的解决
  7. unicode-bidi:设置文本的方向
  8. 盒子模型的属性:width、height、margin、border、padding
  9. 背景属性:background、background-color、background-image、background-repeat、background-position、background-attachment
  10. 定位属性:float、clear、position、top、right、bottom、left、min-width、min-height、max-width、max-height、overflow、clip、z-index
  11. 生成内容属性:content、counter-reset、counter-increment
  12. 轮廓款式属性:outline-style、outline-width、outline-color、outline
  13. 页面款式属性:size、page-break-before、page-break-after
  14. 声音款式属性:pause-before、pause-after、pause、cue-before、cue-after、cue、play-during

二、有继承性的属性

  1. 字体系列属性
  2. font-family:字体系列
  • font-weight:字体的粗细
  • font-size:字体的大小
  • font-style:字体的格调
  • 文本系列属性
  • text-indent:文本缩进
  • text-align:文本程度对齐
  • line-height:行高
  • word-spacing:单词之间的间距
  • letter-spacing:中文或者字母之间的间距
  • text-transform:管制文本大小写(就是 uppercase、lowercase、capitalize 这三个)
  • color:文本色彩
  • 元素可见性
  • visibility:管制元素显示暗藏
  • 列表布局属性
  • list-style:列表格调,包含 list-style-type、list-style-image 等
  • 光标属性
  • cursor:光标显示为何种状态

单行、多行文本溢出暗藏

  • 单行文本溢出
overflow: hidden;            // 溢出暗藏
text-overflow: ellipsis;      // 溢出用省略号显示
white-space: nowrap;         // 规定段落中的文本不进行换行
  • 多行文本溢出
overflow: hidden;            // 溢出暗藏
text-overflow: ellipsis;     // 溢出用省略号显示
display:-webkit-box;         // 作为弹性伸缩盒子模型显示。-webkit-box-orient:vertical; // 设置伸缩盒子的子元素排列形式:从上到下垂直排列
-webkit-line-clamp:3;        // 显示的行数

留神:因为下面的三个属性都是 CSS3 的属性,没有浏览器能够兼容,所以要在后面加一个-webkit- 来兼容一部分浏览器。

手写题:实现柯里化

事后设置一些参数

柯里化是什么:是指这样一个函数,它接管函数 A,并且能返回一个新的函数,这个新的函数可能处理函数 A 的残余参数

function createCurry(func, args) {
  var argity = func.length;
  var args = args || [];

  return function () {var _args = [].slice.apply(arguments);
    args.push(..._args);

    if (args.length < argity) {return createCurry.call(this, func, args);
    }

    return func.apply(this, args);
  }
}

isNaN 和 Number.isNaN 函数的区别?

  • 函数 isNaN 接管参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因而非数字值传入也会返回 true,会影响 NaN 的判断。
  • 函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再持续判断是否为 NaN,不会进行数据类型的转换,这种办法对于 NaN 的判断更为精确。

对浏览器的了解

浏览器的次要性能是将用户抉择的 web 资源出现进去,它须要从服务器申请资源,并将其显示在浏览器窗口中,资源的格局通常是 HTML,也包含 PDF、image 及其他格局。用户用 URI(Uniform Resource Identifier 对立资源标识符)来指定所申请资源的地位。

HTML 和 CSS 标准中规定了浏览器解释 html 文档的形式,由 W3C 组织对这些标准进行保护,W3C 是负责制订 web 规范的组织。然而浏览器厂商纷纷开发本人的扩大,对标准的遵循并不欠缺,这为 web 开发者带来了重大的兼容性问题。

浏览器能够分为两局部,shell 和 内核。其中 shell 的品种绝对比拟多,内核则比拟少。也有一些浏览器并不辨别外壳和内核。从 Mozilla 将 Gecko 独立进去后,才有了外壳和内核的明确划分。

  • shell 是指浏览器的外壳:例如菜单,工具栏等。次要是提供给用户界面操作,参数设置等等。它是调用内核来实现各种性能的。
  • 内核是浏览器的外围。内核是基于标记语言显示内容的程序或模块。

参考 前端进阶面试题具体解答

数组去重

应用 indexOf/includes 实现

function unique(arr) {var res = [];
    for(var i = 0; i < arr.length; i++) {if(res.indexOf(arr[i]) === -1) res.push(arr[i]);
        // if(!res.includes(arr[i])) res.push(arr[i]);
    }
    return res;
}

应用 filter(forEach) + indexOf/includes 实现

// filter
function unique(arr) {var res = arr.filter((value, index) => {
        // 只存第一个呈现的元素
        return arr.indexOf(value) === index;
    });
    return res;
}
// forEach
function unique(arr) {var res = [];
    arr.forEach((value) => {if(!res.includes(value)) res.push(value);
    });
    return res;
}

非 API 版本(原生)实现

function unique(arr) {var res = [];
    for(var i = 0; i < arr.length; i++) {
        var flag = false;
        for(var j = 0; j < res.length; j++) {if(arr[i] === res[j]) {
                flag = true;
                break;
            }
        }
        if(flag === false) res.push(arr[i]);
    }
    return res;
}

ES6 应用 Set + 扩大运算符(…)/Array.from() 实现

function unique(arr) {// return [...new Set(arr)];
    return Array.from(new Set(arr));
}

实现一个宽高自适应的正方形

  • 利用 vw 来实现:
.square {
  width: 10%;
  height: 10vw;
  background: tomato;
}
  • 利用元素的 margin/padding 百分比是绝对父元素 width 的性质来实现:
.square {
  width: 20%;
  height: 0;
  padding-top: 20%;
  background: orange;
}
  • 利用子元素的 margin-top 的值来实现:
.square {
  width: 30%;
  overflow: hidden;
  background: yellow;
}
.square::after {
  content: '';
  display: block;
  margin-top: 100%;
}

柯里化

题目形容: 柯里化(Currying),又称局部求值(Partial Evaluation),是把承受多个参数的函数变换成承受一个繁多参数(最后函数的第一个参数)的函数,并且返回承受余下的参数而且返回后果的新函数的技术。核心思想是把多参数传入的函数拆成单参数(或局部)函数,外部再返回调用下一个单参数(或局部)函数,顺次解决残余的参数。

实现代码如下:

function currying(fn, ...args) {
  const length = fn.length;
  let allArgs = [...args];
  const res = (...newArgs) => {allArgs = [...allArgs, ...newArgs];
    if (allArgs.length === length) {return fn(...allArgs);
    } else {return res;}
  };
  return res;
}

// 用法如下:// const add = (a, b, c) => a + b + c;
// const a = currying(add, 1);
// console.log(a(2,3))

什么是 margin 重叠问题?如何解决?

问题形容: 两个块级元素的上外边距和下外边距可能会合并(折叠)为一个外边距,其大小会取其中外边距值大的那个,这种行为就是外边距折叠。须要留神的是,浮动的元素和相对定位 这种脱离文档流的元素的外边距不会折叠。重叠只会呈现在 垂直方向

计算准则: 折叠合并后外边距的计算准则如下:

  • 如果两者都是负数,那么就去最大者
  • 如果是一正一负,就会正值减去负值的绝对值
  • 两个都是负值时,用 0 减去两个中绝对值大的那个

解决办法: 对于折叠的状况,次要有两种:兄弟之间重叠 父子之间重叠(1)兄弟之间重叠

  • 底部元素变为行内盒子:display: inline-block
  • 底部元素设置浮动:float
  • 底部元素的 position 的值为absolute/fixed

(2)父子之间重叠

  • 父元素退出:overflow: hidden
  • 父元素增加通明边框:border:1px solid transparent
  • 子元素变为行内盒子:display: inline-block
  • 子元素退出浮动属性或定位

代码输入后果

var friendName = 'World';
(function() {if (typeof friendName === 'undefined') {
    var friendName = 'Jack';
    console.log('Goodbye' + friendName);
  } else {console.log('Hello' + friendName);
  }
})();

输入后果:Goodbye Jack

咱们晓得,在 JavaScript 中,Function 和 var 都会被晋升(变量晋升),所以下面的代码就相当于:

var name = 'World!';
(function () {
    var name;
    if (typeof name === 'undefined') {
        name = 'Jack';
        console.log('Goodbye' + name);
    } else {console.log('Hello' + name);
    }
})();

这样,答案就高深莫测了。

line-height 的了解及其赋值形式

(1)line-height 的概念:

  • line-height 指一行文本的高度,蕴含了字间距,实际上是下一行基线到上一行基线间隔;
  • 如果一个标签没有定义 height 属性,那么其最终体现的高度由 line-height 决定;
  • 一个容器没有设置高度,那么撑开容器高度的是 line-height,而不是容器内的文本内容;
  • 把 line-height 值设置为 height 一样大小的值能够实现单行文字的垂直居中;
  • line-height 和 height 都能撑开一个高度;

(2)line-height 的赋值形式:

  • 带单位:px 是固定值,而 em 会参考父元素 font-size 值计算本身的行高
  • 纯数字:会把比例传递给后辈。例如,父级行高为 1.5,子元素字体为 18px,则子元素行高为 1.5 * 18 = 27px
  • 百分比:将计算后的值传递给后辈

三栏布局的实现

三栏布局个别指的是页面中一共有三栏,左右两栏宽度固定,两头自适应的布局,三栏布局的具体实现:

  • 利用 相对定位,左右两栏设置为相对定位,两头设置对应方向大小的 margin 的值。
.outer {
  position: relative;
  height: 100px;
}

.left {
  position: absolute;
  width: 100px;
  height: 100px;
  background: tomato;
}

.right {
  position: absolute;
  top: 0;
  right: 0;
  width: 200px;
  height: 100px;
  background: gold;
}

.center {
  margin-left: 100px;
  margin-right: 200px;
  height: 100px;
  background: lightgreen;
}
  • 利用 flex 布局,左右两栏设置固定大小,两头一栏设置为 flex:1。
.outer {
  display: flex;
  height: 100px;
}

.left {
  width: 100px;
  background: tomato;
}

.right {
  width: 100px;
  background: gold;
}

.center {
  flex: 1;
  background: lightgreen;
}
  • 利用浮动,左右两栏设置固定大小,并设置对应方向的浮动。两头一栏设置左右两个方向的 margin 值,留神这种形式,两头一栏必须放到最初:
.outer {height: 100px;}

.left {
  float: left;
  width: 100px;
  height: 100px;
  background: tomato;
}

.right {
  float: right;
  width: 200px;
  height: 100px;
  background: gold;
}

.center {
  height: 100px;
  margin-left: 100px;
  margin-right: 200px;
  background: lightgreen;
}
  • 圣杯布局,利用浮动和负边距来实现。父级元素设置左右的 padding,三列均设置向左浮动,两头一列放在最后面,宽度设置为父级元素的宽度,因而前面两列都被挤到了下一行,通过设置 margin 负值将其挪动到上一行,再利用绝对定位,定位到两边。
.outer {
  height: 100px;
  padding-left: 100px;
  padding-right: 200px;
}

.left {
  position: relative;
  left: -100px;

  float: left;
  margin-left: -100%;

  width: 100px;
  height: 100px;
  background: tomato;
}

.right {
  position: relative;
  left: 200px;

  float: right;
  margin-left: -200px;

  width: 200px;
  height: 100px;
  background: gold;
}

.center {
  float: left;

  width: 100%;
  height: 100px;
  background: lightgreen;
}
  • 双飞翼布局,双飞翼布局绝对于圣杯布局来说,左右地位的保留是通过两头列的 margin 值来实现的,而不是通过父元素的 padding 来实现的。实质上来说,也是通过浮动和外边距负值来实现的。
.outer {height: 100px;}

.left {
  float: left;
  margin-left: -100%;

  width: 100px;
  height: 100px;
  background: tomato;
}

.right {
  float: left;
  margin-left: -200px;

  width: 200px;
  height: 100px;
  background: gold;
}

.wrapper {
  float: left;

  width: 100%;
  height: 100px;
  background: lightgreen;
}

.center {
  margin-left: 100px;
  margin-right: 200px;
  height: 100px;
}

应用 clear 属性革除浮动的原理?

应用 clear 属性革除浮动,其语法如下:

clear:none|left|right|both

如果单看字面意思,clear:left 是“革除左浮动”,clear:right 是“革除右浮动”,实际上,这种解释是有问题的,因为浮动始终还在,并没有革除。

官网对 clear 属性解释:“元素盒子的边不能和后面的浮动元素相邻”,对元素设置 clear 属性是为了防止浮动元素对该元素的影响,而不是革除掉浮动。

还须要留神 clear 属性指的是元素盒子的边不能和后面的浮动元素相邻,留神这里“后面的”3 个字,也就是 clear 属性对“前面的”浮动元素是充耳不闻的。思考到 float 属性要么是 left,要么是 right,不可能同时存在,同时因为 clear 属性对“前面的”浮动元素充耳不闻,因而,当 clear:left 无效的时候,clear:right 必然有效,也就是此时 clear:left 等同于设置 clear:both;同样地,clear:right 如果无效也是等同于设置 clear:both。由此可见,clear:left 和 clear:right 这两个申明就没有任何应用的价值,至多在 CSS 世界中是如此,间接应用 clear:both 吧。

个别应用伪元素的形式革除浮动:

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

clear 属性只有块级元素才无效的,而::after 等伪元素默认都是内联程度,这就是借助伪元素革除浮动影响时须要设置 display 属性值的起因。

什么是中间人攻打?如何防备中间人攻打?

两头⼈ (Man-in-the-middle attack, MITM) 是指攻击者与通信的两端别离创立独⽴的分割, 并替换其所收到的数据, 使通信的两端认为他们正在通过⼀个私密的连贯与对⽅直接对话, 但事实上整个会话都被攻击者齐全管制。在两头⼈攻打中,攻击者能够拦挡通信双⽅的通话并插⼊新的内容。

攻打过程如下:

  • 客户端发送申请到服务端,申请被两头⼈截获
  • 服务器向客户端发送公钥
  • 两头⼈截获公钥,保留在⾃⼰⼿上。而后⾃⼰⽣成⼀个 伪造的 公钥,发给客户端
  • 客户端收到伪造的公钥后,⽣成加密 hash 值发给服务器
  • 两头⼈取得加密 hash 值,⽤⾃⼰的私钥解密取得真秘钥, 同时⽣成假的加密 hash 值,发给服务器
  • 服务器⽤私钥解密取得假密钥, 而后加密数据传输给客户端

IndexedDB 有哪些特点?

IndexedDB 具备以下特点:

  • 键值对贮存:IndexedDB 外部采纳对象仓库(object store)存放数据。所有类型的数据都能够间接存入,包含 JavaScript 对象。对象仓库中,数据以 ” 键值对 ” 的模式保留,每一个数据记录都有对应的主键,主键是举世无双的,不能有反复,否则会抛出一个谬误。
  • 异步:IndexedDB 操作时不会锁死浏览器,用户仍然能够进行其余操作,这与 LocalStorage 造成比照,后者的操作是同步的。异步设计是为了避免大量数据的读写,拖慢网页的体现。
  • 反对事务:IndexedDB 反对事务(transaction),这意味着一系列操作步骤之中,只有有一步失败,整个事务就都勾销,数据库回滚到事务产生之前的状态,不存在只改写一部分数据的状况。
  • 同源限度: IndexedDB 受到同源限度,每一个数据库对应创立它的域名。网页只能拜访本身域名下的数据库,而不能拜访跨域的数据库。
  • 贮存空间大:IndexedDB 的贮存空间比 LocalStorage 大得多,一般来说不少于 250MB,甚至没有下限。
  • 反对二进制贮存:IndexedDB 不仅能够贮存字符串,还能够贮存二进制数据(ArrayBuffer 对象和 Blob 对象)。

实现模板字符串解析

形容 :实现函数使得将 template 字符串中的{{}} 内的变量替换。

外围:应用字符串替换办法 str.replace(regexp|substr, newSubStr|function),应用正则匹配代换字符串。

实现

function render(template, data) {// 模板字符串正则 /\{\{(\w+)\}\}/, 加 g 为全局匹配模式, 每次匹配都会调用前面的函数
    let computed = template.replace(/\{\{(\w+)\}\}/g, function(match, key) {
        // match: 匹配的子串;  key:括号匹配的字符串
        return data[key];
    });
    return computed;
}

// 测试
let template = "我是{{name}},年龄{{age}},性别{{sex}}";
let data = {
  name: "张三",
  age: 18
}
console.log(render(template, data)); // 我是张三,年龄 18,性别 undefined

常见浏览器所用内核

(1)IE 浏览器内核:Trident 内核,也是俗称的 IE 内核;

(2)Chrome 浏览器内核:统称为 Chromium 内核或 Chrome 内核,以前是 Webkit 内核,当初是 Blink 内核;

(3)Firefox 浏览器内核:Gecko 内核,俗称 Firefox 内核;

(4)Safari 浏览器内核:Webkit 内核;

(5)Opera 浏览器内核:最后是本人的 Presto 内核,起初退出谷歌大军,从 Webkit 又到了 Blink 内核;

(6)360 浏览器、猎豹浏览器内核:IE + Chrome 双内核;

(7)搜狗、漫游、QQ 浏览器内核:Trident(兼容模式)+ Webkit(高速模式);

(8)百度浏览器、世界之窗内核:IE 内核;

(9)2345 浏览器内核:如同以前是 IE 内核,当初也是 IE + Chrome 双内核了;

(10)UC 浏览器内核:这个众口不一,UC 说是他们本人研发的 U3 内核,但如同还是基于 Webkit 和 Trident,还有说是基于火狐内核。

对 CSSSprites 的了解

CSSSprites(精灵图),将一个页面波及到的所有图片都蕴含到一张大图中去,而后利用 CSS 的 background-image,background-repeat,background-position 属性的组合进行背景定位。

长处:

  • 利用 CSS Sprites 能很好地缩小网页的 http 申请,从而大大提高了页面的性能,这是 CSS Sprites 最大的长处;
  • CSS Sprites能缩小图片的字节,把 3 张图片合并成 1 张图片的字节总是小于这 3 张图片的字节总和。

毛病:

  • 在图片合并时,要把多张图片有序的、正当的合并成一张图片,还要留好足够的空间,避免板块内呈现不必要的背景。在宽屏及高分辨率下的自适应页面,如果背景不够宽,很容易呈现背景断裂;
  • CSSSprites在开发的时候相对来说有点麻烦,须要借助 photoshop 或其余工具来对每个背景单元测量其精确的地位。
  • 保护方面:CSS Sprites在保护的时候比拟麻烦,页面背景有少许改变时,就要改这张合并的图片,无需改的中央尽量不要动,这样防止改变更多的CSS,如果在原来的中央放不下,又只能(最好)往下加图片,这样图片的字节就减少了,还要改变CSS

Promise.resolve

Promise.resolve = function(value) {
    // 1. 如果 value 参数是一个 Promise 对象,则一成不变返回该对象
    if(value instanceof Promise) return value;
    // 2. 如果 value 参数是一个具备 then 办法的对象,则将这个对象转为 Promise 对象,并立刻执行它的 then 办法
    if(typeof value === "object" && 'then' in value) {return new Promise((resolve, reject) => {value.then(resolve, reject);
        });
    }
    // 3. 否则返回一个新的 Promise 对象,状态为 fulfilled
    return new Promise(resolve => resolve(value));
}

正文完
 0