面试题第九期

126 阅读17分钟

10月20号

1、valueOf 与 toString

  • 1、valueOf偏向于运算,toString偏向于显示
  • 2、对象转换时,优先调用toString
  • 3、强转字符串优先调用toString,强转数字优先调用valueOf
  • 4、正常情况下,优先调用toString
  • 5、运算操作符情况下优先调用valueOf

调用valueOf

调用者返回值返回值类型
Array数组本身Array
Boolean布尔值Boolean
Date毫秒数Number
Function函数本身Function
Number数字值Number
Object对象本身Object
String字符串String

调用toString

调用者返回值返回值类型
Array数组转字符串,相当于Array.join()String
Boolean转字符串'true'、'false'String
Date字符串日期,如'Fri Dec 23 2016 11:24:47 GMT+0800 (中国标准时间)'String
Number数字字符串String
Object'[object Object]'String
String字符串

2 字符串数组常用方法

字符串方法

var a="i love you!";
  1. toUpperCase() 将小写转换成大写
  2. toLowerCase() 将大写转换成小写
  3. charAt() 返回指定位置的字符
document.write(a.charAt(4));//结果是v
// 注:字符是从0开始到length-1结束
  1. indexOf() 返回指定字符的位置
document.write(a.charAt(v));//结果是4
  1. lastIndexOf()
  2. split() 返回被分割的字符串数组
document.write(a,split("v",2));//结果是["i lo","e you!"]
// 注:前面指定分割的位置,不填则分割成一个个字符;后面指定分割组数,可不填
  1. substring() 提取字符串
document.write(a.substring(2,5));//结果是love
document.write(a.substring(7));//结果是you!
// 注:前面指定开始提取的位置;后面指定结束提取的位置,不填则默认到字符串最后
  1. subsrt() 提取指定数目字符串
document.write(a.substr(2,4));//结果是love
document.write(a.substr(-4));//结果是you!
// 注:前面指定开始提取的位置;后面指定提取的长度,不填则默认到字符串最后;若出现-,则表示倒着数

数组方法

  1. concat() 连接数组,不改变原数组,返回一个新数组
var a=["1","2"];
var b=["3","4"];
document.write(a.concat(b));
//结果是["1","2","3","4"]
  1. join() 用指定分隔符连接数组元素,返回string
var a=["I","love","you"];
document.write(a.join("."));//结果是I.love.you
// 注:若不指定,默认","
  1. reverse() 颠倒数组元素顺序,会改变原数组
var a=["1","2"];
document.write(a.reverse());//结果是["2","1"]
  1. slice() 选定元素,不改变原数组,返回一个子数组
var a=["1","2","3","4"];
document.write(a.slice(2,4));//结果是["3","4"];
// 注:前面指定开始选定的位置,注意不包括这个位置;后面指定结束选定的位置,不填则默认到字符串最后;若出现-,则表示倒着数
  1. sort() 数组排序
function a(x,y){return x-y;}
//升序,若降序,return y-x;
var b=["1","7","5","3"];
document.write(b.sort(a));
//结果是["1","3","5","7"]
  1. slice(start,end) 截取指定索引之间的字符串(包括start,不包括end),返回新的字符串
var str = "abcdaefga";
console.log(str.slice(1,5)); // "cda"

  1. subString(start,stop) 截取指定索引之间的字符串(包括start,不包括stop),返回新的字符串
var str = "abcdaefga";
console.log(str.slice(1,5)); // "cda"

  1. charAt(index) 返回指定位置的字符
var str = "abcde";
console.log(str.charAt(3)); // d
  1. concat(str) 连接字符串,生成一个新的字符串,原字符串不会被改变
var str1 = "abc";
var str2 = "def";
console.log(str1.concat(str2)); // “abcdef”
  1. trim()去掉字符串的首尾的空格,返回新的字符串
var str = "  abcd  ";
console.log(str.trim()); // "abcd"

3 URI 的结构

URI 真正最完整的结构是这样的。

scheme 表示协议名,比如http, https, file等等。后面必须和://连在一起。

user:passwd@ 表示登录主机时的用户信息,不过很不安全,不推荐使用,也不常用。

host:port表示主机名和端口。

path表示请求路径,标记资源所在位置。

query表示查询参数,为key=val这种形式,多个键值对之间用&隔开。

fragment表示 URI 所定位的资源内的一个锚点,浏览器可以根据这个锚点跳转到对应的位置。

4 http 状态码

1.1 状态码分类

  • 1xx - 服务器收到请求。
  • 2xx - 请求成功,如 200。
  • 3xx - 重定向,如 302。
  • 4xx - 客户端错误,如 404。
  • 5xx - 服务端错误,如 500。

1.2 常见状态码

  • 200 - 成功。
  • 301 - 永久重定向(配合 location,浏览器自动处理)。
  • 302 - 临时重定向(配合 location,浏览器自动处理)。
  • 304 - 资源未被修改。
  • 403 - 没权限。
  • 404 - 资源未找到。
  • 500 - 服务器错误。
  • 504 - 网关超时。

1.3 关于协议和规范

  • 状态码都是约定出来的。
  • 要求大家都跟着执行。
  • 不要违反规范,例如 IE 浏览器。

2、http 缓存

  • 关于缓存的介绍。
  • http 缓存策略(强制缓存 + 协商缓存)。
  • 刷新操作方式,对缓存的影响。

3.1 关于缓存

什么是缓存? 把一些不需要重新获取的内容再重新获取一次

为什么需要缓存? 网络请求相比于 CPU 的计算和页面渲染是非常非常慢的。

哪些资源可以被缓存? 静态资源,比如 js css img。

三种刷新操作对 http 缓存的影响

  • 正常操作:地址栏输入 url,跳转链接,前进后退等。
  • 手动刷新:f5,点击刷新按钮,右键菜单刷新。
  • 强制刷新:ctrl + f5,shift+command+r。

正常操作:强制缓存有效,协商缓存有效。  手动刷新:强制缓存失效,协商缓存有效。  强制刷新:强制缓存失效,协商缓存失效

5 GET 和 POST 的区别。

  • 缓存的角度,GET 请求会被浏览器主动缓存下来,留下历史记录,而 POST 默认不会。
  • 编码的角度,GET 只能进行 URL 编码,只能接收 ASCII 字符,而 POST 没有限制。
  • 参数的角度,GET 一般放在 URL 中,因此不安全,POST 放在请求体中,更适合传输敏感信息。
  • 幂等性的角度,GET 是幂等的,而 POST 不是。(幂等表示执行相同的操作,结果也是相同的)
  • TCP 的角度,GET 请求会把请求报文一次性发出去,而 POST 会分为两个 TCP 数据包,首先发 header 部分,如果服务器响应 100(continue), 然后发 body 部分。(火狐浏览器除外,它的 POST 请求只发一个 TCP 包)

6 HTTP/2 有哪些改进?

  • 头部压缩。
  • 多路复用。
  • 服务器推送。

7 https为什么是安全的

https保证数据以更保密的方式传输,并增加对服务器身份验证,这可以使我们的数据传输更安全,有效防止数据的泄露和篡改。

10月21日

1.函数的length是多少?

形参个数

咱们来看看下面这个例子

function fn1 () {}

function fn2 (name) {}

function fn3 (name, age) {}

console.log(fn1.length) // 0
console.log(fn2.length) // 1
console.log(fn3.length) // 2

可以看出,function有多少个形参,length就是多少

默认参数

如果有默认参数的话,函数的length会是多少呢?

function fn1 (name) {}

function fn2 (name = '程林海') {}

function fn3 (name, age = 22) {}

function fn4 (name, age = 22, gender) {}

function fn5(name = '程林海', age, gender) { }

console.log(fn1.length) // 1
console.log(fn2.length) // 0
console.log(fn3.length) // 1
console.log(fn4.length) // 1
console.log(fn5.length) // 0

说明了,functionlength,就是第一个具有默认值之前的参数个数

剩余参数

在函数的形参中,还有剩余参数这个东西,那如果具有剩余参数,会是怎么算呢?

function fn1(name, ...args) {}

console.log(fn1.length) // 1

可以看出,剩余参数是不算进length的计算之中的

总结就是length 是函数对象的一个属性值,指该函数有多少个必须要传入的参数,即形参的个数。形参的数量不包括剩余参数个数,仅包括第一个具有默认值之前的参数个数

2、数组的splice 与 slice 的区别?

方法参数描述
splicesplice(start, num, item1, item2, ...)从start索引开始,截取num个元素,并插入item1、item2到原数组里,影响原数组
sliceslice(start, end)从start开始,截取到end - 1,如果没有end,则截取到最后一个元素,不影响原数组

3、substr 和 substring 的区别?

方法参数描述
substrsubstr(start,length)返回从start位置开始length长度的子串
substringsubstring(start,end)返回从start位置开始到end位置的子串(不包含end)

4、includes 比 indexOf好在哪?

includes可以检测NaN,indexOf不能检测NaN,includes内部使用了Number.isNaNNaN进行了匹配

5.JS延迟加载的方法有哪些?

  • 1、<script async src="script.js"></script>:给script标签加async属性,则加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)
  • 2、<script defer src="script.js"></script>:给script标签加defer属性,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成
  • 3、动态创建script标签:等到DOMContentLoaded 事件触发时,生成一个script标签,渲染到页面上上
  • 4、setTimeout定时器延迟代码执行

6、鼠标事件有哪些?

注明:鼠标左中右键看event对象上的button属性,对应1、2、3

事件说明
click单机鼠标左键触发,右键无效,当用户焦点在按钮并按下Enter,也会触发
dbclick双击鼠标左键触发,右键无效
mousedown单机鼠标任意一个按键都触发
mouseout鼠标指针位于某个元素上且将要移出元素边界时触发
mouseover鼠标指针移出某个元素到另一个元素上时触发
mouseup鼠标指针移出某个元素到另一个元素上时触发
mouseover松开任意鼠标按键时触发
mousemove鼠标在某个元素上时持续发生
mouseenter鼠标进入某个元素边界时触发
mouseleave鼠标离开某个元素边界时触发

7、键盘事件有哪些?

注明:event对象上的keyCode属性,是按下的按键的ASCLL值,通过这个值可辨别是按下哪个按键。ASCLL表在此ASCII码一览表,ASCII码对照表

事件说明
onkeydown某个键盘按键被按下时触发
onkeyup某个键盘按键被松开时触发
onkeypress某个按键被按下时触发,不监听功能键,如ctrl,shift

8、JS中鼠标事件的各个坐标?

属性说明兼容性
offsetX以当前的目标元素左上角为原点,定位x轴坐标除Mozilla外都兼容
offsetY以当前的目标元素左上角为原点,定位y轴坐标除Mozilla外都兼容
clientX以浏览器可视窗口左上角为原点,定位x轴坐标都兼容
clientY以浏览器可视窗口左上角为原点,定位y轴坐标都兼容
pageX以doument对象左上角为原点,定位x轴坐标除IE外都兼容
pageY以doument对象左上角为原点,定位y轴坐标除IE外都兼容
screenX以计算机屏幕左上顶角为原点,定位x轴坐标(多屏幕会影响)全兼容
screenY以计算机屏幕左上顶角为原点,定位y轴坐标全兼容
layerX最近的绝对定位的父元素(如果没有,则为 document 对象)左上顶角为元素,定位 x 轴坐标Mozilla 和 Safari
layerY最近的绝对定位的父元素(如果没有,则为 document 对象)左上顶角为元素,定位 y 轴坐标Mozilla 和 Safari

9、JS中元素视图的各个尺寸?

属性说明
offsetLeft获取当前元素到定位父节点的left方向的距离
offsetTop获取当前元素到定位父节点的top方向的距离
offsetWidth获取当前元素 width + 左右padding + 左右border-width
offsetHeight获取当前元素 height + 上下padding + 上下border-width
clientWidth获取当前元素 width + 左右padding
clientHeight获取当前元素 height + 上下padding
scrollWidth当前元素内容真实的宽度,内容不超出盒子宽度时为盒子的clientWidth
scrollHeight当前元素内容真实的高度,内容不超出盒子高度时为盒子的clientHeight

10、Window视图的各个尺寸?

属性说明
innerWidthinnerWidth 浏览器窗口可视区宽度(不包括浏览器控制台、菜单栏、工具栏)
innerHeightinnerWidth 浏览器窗口可视区高度(不包括浏览器控制台、菜单栏、工具栏)

11、Document文档视图的各个尺寸?

属性说明
document.documentElement.clientWidth浏览器窗口可视区宽度(不包括浏览器控制台、菜单栏、工具栏、滚动条)
document.documentElement.clientHeight浏览器窗口可视区高度(不包括浏览器控制台、菜单栏、工具栏、滚动条)
document.documentElement.offsetHeight获取整个文档的高度(包含body的margin)
document.body.offsetHeight获取整个文档的高度(不包含body的margin)
document.documentElement.scrollTop返回文档的滚动top方向的距离(当窗口发生滚动时值改变)
document.documentElement.scrollLeft返回文档的滚动left方向的距离(当窗口发生滚动时值改变)

10月22日

1. 实现模板字符串解析功能

let template = '我是{{name}},年龄{{age}},性别{{sex}}';
let data = {
  name: '姓名',
  age: 18
}
render(template, data); // 我是姓名,年龄18,性别undefined

function render(template, data){
  let computed=template.replace(/\{\{(\w+)\}\}/g,function(match, key){
    return data[key]
  })
 return computed
}
let data2= render(template, data); // 我是姓名,年龄18,性别undefined
console.log(data2);

2.css有哪些基本的选择器,执行先后顺序?

类选择器(class)、标签选择器、ID选择器

!important>内联样式(非选择器)>ID选择器>类选择器>标签选择器>通配符选择器(*)

3.清除浮动

1、父级div定义overflow:hidden(如果父级元素有定位元素超出父级,超出部分会隐藏,)

2、在浮动元素后面加一个空标签,clear:both;height: 0;overflow:hidden

3、伪元素清除浮动:给浮动元素父级增加 .clearfix::after(content: ‘’; display: table; clear: both;)(不会新增标签,不会有其他影响,)

4.常用的块与行属性内标签有哪些?有什么特征

块标签:div、h1~h6、ul、li、table、p、br、form。

特征:独占一行,换行显示,可以设置宽高,可以嵌套块和行

行标签:span、a、img、textarea、select、option、input。

特征:只有在行内显示,内容撑开宽、高,不可以设置宽、高(img、input、textarea等除外)。

5.CSS中有哪些长度单位?

绝对长度单位:px

百分比: %

相对父元素字体大小单位: em

相对于根元素字体大小的单位: rem

相对于视口*宽度的百分比(100vw即视窗宽度的100%): vw

相对于视口*高度的百分比(100vh即视窗高度的100%): vh

6.display:none和visibility:hidden的区别

display:block、inline、inline-block、flex

display:none:隐藏元素,在文档布局中不在给它分配空间(从文档中移除),会引起回流(重排)。

visibility:hidden: 隐藏元素,但是在文档布局中仍保留原来的空间(还在文档中),不会引起回流(重绘)。

 7.flex原理

  •   实现 flex 布局需要先指定一个容器,任何一个容器都可以被指定为 flex 布局,这样容器内部的元素就可以使用 flex 来进行布局。
  • flex-direction
  • flex-wrap
  • flex-flow
  • justify-content
  • align-items
  • align-content

  8.BFC

  •   z-index作用:控制元素重叠时堆叠顺序
  •   元素的层级

9.定位的属性值有何区别

css里面的定位

  • 相对定位

    • 不会脱离文档流
    • 元素的微调
    • 作为绝对定位的参照元素(子绝父相)
  • 绝对定位

    • 脱离文档流
    • 必须要存在一个参照的元素(一般来说是自己 的父元素;如果父元素没有定位,则会继续向外查找,直到找到一个离自己最近的已经定位了的元素作为参考,如果实在没有,找 body 进行定位)
  • 固定定位

    • 一般用于相当于当前视窗进行定位
    • 对联广告
    • 回到定位
    • 吸顶效果

10月23日

第一题

尝试推测它的输出:

const person = { name: '代码与野兽' }
Object.defineProperty(person, 'age', { value: 18 })

console.log(person.age)
console.log(Object.keys(person))

输出:

18
['name']

解析:
很多人容易搞错第二个输出,因为使用 defineProperty 定义的属性默认是不可枚举的。

第二题

尝试推测它的输出:

const name = '代码与野兽'
age = 18

console.log(delete name)
console.log(delete age)
console.log(typeof age)

输出:

false
true
"undefined"

解析:
第一个 false 是因为 delete 只能删除对象上的属性,name 不是属性,所以删除失败。
第二个 true 是因为我们不使用任何声明创建变量,它会被视作全局变量,挂载到 window 对象上面,等价于 delete window.age,所以删除成功。
第三个 undefined 是因为 age 被删除了。

第三题

尝试推测它的输出:

let person = { name: '代码与野兽' }
const members = [person]
person = null
console.log(members)

输出:

[{  name: "代码与野兽"}]

解析:
很多人会认为输出结果应该是 [ null ],但是,我们只是设置了 person 这个变量的新引用,之前的引用还在 members 中。
简单来说,{ name: '代码与野兽' } 这个对象存在某个内存空间中,假设它的地址是 X201。它的逻辑大概像下面这样:

let person = X201
const members = [X201]
persion = null

第四题

尝试推测它的输出:

function SuperHero() {
  this.make = '代码与野兽'
  return { make: '野兽与代码'}
}

const mySuperhero = new SuperHero()
console.log(mySuperhero)

输出:

{
  make: "野兽与代码"
}

解析:
如果构造函数最终返回了一个对象,那么之前设置的属性都将失效。

第五题

尝试推测它的输出:

const name = '代码与野兽'
console.log(name.padStart(14))
console.log(name.padStart(2))

输出:

"         代码与野兽"
"代码与野兽"

解析:
padStart 方法可以在字符串的开头填充空格。
参数是新字符串的总长度,如果这个长度比原来的字符串长度短,那么不会填充。

第六题

尝试推测它的输出:

console.log(parseInt("7"))
console.log(parseInt("7*6"))
console.log(parseInt("7Din"))

输出:

7
7
7

解析:
如果 parseInt 的参数是字符串和数字的组合,那么它会从头开始检查,直到碰到数据类型错误的位置,如果在数据类型错误的位置之前是一个有效的数字,它就会返回数字。

第七题

尝试推测它的输出:

[1, 2, 3, 4].reduce((x, y) => console.log(x, y))

输出:

1
2
undefined
3
undefined
4

解析:
如果我们不给 reduce 传递初始值,那么 x 会是数组的第一个值,y 是数组的第二个值。

第八题

尝试推测它的输出:

function getUserInfo(one, two, three) {
  console.log(one)
  console.log(two)
  console.log(three)
}

const superHero = '代码与野兽'
const age = 1000

getUserInfo`${superHero}${age} 岁`
getUserInfo`hello`

输出:

["", " 是 ", " 岁"]
"代码与野兽"
1000
["hello"]
undefined
undefined

解析:
我们使用模板字符串语法去调用函数时,第一个参数始终都是分割好的字符串数组。其余的参数是模板表达式的值。

第九题

尝试推测它的输出:

(() => {
  let x, y;
  try {
    throw new Error()
  } catch (x) {
    (x = 1), (y = 2);
    console.log(x)
  }
  console.log(x)
  console.log(y)
})()

输出:

1
undefined
2

解析:
在 catch 中访问 x,访问的是参数,而不是外面的变量 x。

第十题

尝试推测它的输出:

class Clazz {}

console.log(typeof Clazz)

输出:

"function"

解析:
在 JavaScript 中,Class 也是 function。

第十一题

尝试推测它的输出:

const arr = [7, 1, 4, 3, 2];
for (const elem of arr) {
  setTimeout(() => console.log(elem), elem);
}

输出:

1
2
3
4
7

解析:
没什么好解释的......

第十二题

尝试推测它的输出:

const foo = { bar: 1 };
with(foo) {
  var bar = 2
};
console.log(foo.bar);

输出:

2

解析:
with 的对象会作为 global 对象。在 with 使用 var 等价于 window.[xxx]。而这时 foo 就是那个 window。

13 实现 三栏布局 说出多种方法

5.1 flex实现
外层盒子设置dispaly:flex;
左右两个盒子设置width:100px;
中间盒子设置flex:1;

5.2 grid实现
外层盒子设置grid-template-columns: 100px 1fr 100px;

5.3 浮动 + calc实现
左侧盒子设置float:left;
右侧盒子设置float:right;
中间盒子设置float:left; width:calc(100% - 100px);

5.3 浮动 + margin实现
左侧盒子设置float:left;
右侧盒子设置float:right;
中间盒子设置margin:0 100px

14 vue 中使用了哪些设计模式

1.工厂模式 - 传入参数即可创建实例

虚拟 DOM 根据参数的不同返回基础标签的 Vnode 和组件 Vnode

2.单例模式 - 整个程序有且仅有一个实例

vuex 和 vue-router 的插件注册方法 install 判断如果系统存在实例就直接返回掉

3.发布-订阅模式 (vue 事件机制)

4.观察者模式 (响应式数据原理)

5.装饰模式: (@装饰器的用法)

6.策略模式 策略模式指对象有某个行为,但是在不同的场景中,该行为有不同的实现方案-比如选项的合并策略