面试后总结

365 面试

  1. 什么是闭包?带来的问题?如何解决?

能读取其他函数内部变量的函数.
内存泄漏
let fn() = null

  1. JS 的基本类型和引用类型.

基本类型: String,number,Boolean,undefined,null,symbol.
引用类型: Object.(又可以分为对象,数组,函数,正则)

  1. let a = {name:123}, let b= a, b.name = 456,console.log(a.name)?

b.age = 13.console.log(a.age)?
输出 456 和 13.
原因: 对象是引用类型,将值保存在堆内存中.对象的值只是将指针指向堆内存中的数据.
当堆内存中数据改变,自然指向的值也会改变.

  1. let a = 123.let b=a.b=456,console.log(a)?

输出 123.

  1. innerHTML 和 innerText 的区别?

innerHTML 设置或获取元素 html 结构,再写入是会自动构建 DOM.
innerText 设置或获取元素内包含的文字内容.

  1. 创建 DOM 节点的方式?

doument.createElement()
document.write()
document.innerHTML()

  1. JS 改变 this 指向的方法.区别

bind,apply.call
区别: bind 改变 this 指向,返回一个新函数.将函数内部的 this 设置为传入的第一个参数.并不立即执行.
call.apply 会调用函数,传入上下文和其参数,并立即执行.在写法上有区别.
call 只接受两个参数,一个 this 指向的对象,另一个是数组或者类数组.
apply 除了第一个对象外,可以接收多个参数.

1
2
3
4
5
6
7
<input id='btn' type='button' value='123' />
<script>
var value = '456'
document.getElementById('btn').onclick = function(){
console.log(this.value) //打印123
}
</script>
  1. new 一个对象经历那些过程?

  2. 创建新对象. 2.将新对象的原型绑定到构造函数的原型上. 3.将构造函数的作用域赋值给新对象(因此 this 指向了这个对象). 4.执行构造函数中的代码(为新对象添加属性) 5.返回新对象.

1
2
3
4
5
6
7
8
9
10
//构造函数
function Person(name) {
this.name = name;
}
function newFunc(name) {
var o = {};
o.__proto__ = Person.prototype;
Person.call(o, name);
return o;
}

实现一个new

1
2
3
4
5
6
7
function create() {
let obj = {};
let Con = [].shift.call(arguments);
obj.__proto__ = Con.prototype;
let result = Con.apply(obj, arguments);
return result instanceof Object ? result : obj;
}
  1. map 和 for 循环的区别

map:对传入数组进行处理,返回一个新数组,原数组不做改变.
for:遍历数组的方法.

  1. Vue 中 created 和 mounted 有什么区别?请求数据在那个生命周期?

页面已经创建还未挂载到 DOM 节点上.
mounted 属于已经挂载到 DOM 上.
初始化数据一般放在 created(),如果需要改变 DOM 放在 mounted()

小明面试题

  1. 判断类型的几种方法.

instanceof
typeof
constructor
toString(obj 类型直接使用 toSting,而其他类型需要 call=>Object.prototype.toString.call(12) //[object Number]

  1. 原生 JS 怎么获取一个元素的宽度.

document.getElementById(‘div’).offsetWidth

  1. 遍历数组和对象的几种方法

map,forEach,for,for..in,for…of

  1. 权限鉴定
  2. vue 中兄弟组件传值

定义一个 bus 中介,使用 eventBus,将值传给 bus,再从 bus 中传给兄弟

  1. 实现一个方法判断入参是否为 JSON
1
2
3
typeof str == "object" &&
Object.prototype.toString.call(str).toLowerCase() == "[object Object]" &&
!str.length;
  1. 常见的伪数组有那些?怎么转化为真数组

无法调用数组的全部方法,但是仍可以用遍历.
特点: 按索引方式存储数据,具有 length 属性,没有数组的 push,shift,pop 等方法.
常见: function 的 arguments 对象,getELementsByTagName 等 NodeList 对象.
转化方法:
使用Array.prototype.slice.call()
使用Array.from()
使用[].slice.call()

  1. 如何在 node 工程中添加自定义指令和环境变量

npm script 编辑
开发环境:env_develop
生成环境:env_production

  1. 封装 http 请求以及 restful 的了解
1
2
3
4
5
6
7
8
const http = function(...options){
const { type,
return new Promise(resolve,reject){
resolve()
}catch(){
reject()
}
}

RESTful:

  1. 使用 HTTP 动词表示增删改查(CRUD)资源, GET:查询,POST:新增,PUT:更新,DELETE:删除
  2. URL 设计.URL 里使用名词而不是动词.名词最好是复数形式.减少层级,除了第一级,其他使用字符串表示.
  3. 状态码.状态码必须精确
  4. 服务器响应. 不要返回纯文本.应该返回 JSON 对象.
  5. 多个 promise 如何处理?保持顺序如何处理

Promise.all()
Promise.race()
async/await

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//使用reduce
function run(arr, value) {
return arr.reduce((a, b) => a.then(b), Promise.resolve(value));
}
// promise function 1
function p1(a) {
return new Promise((resolve, reject) => {
resolve(a * 5);
});
}
// promise function 2
function p2(a) {
return new Promise((resolve, reject) => {
resolve(a * 2);
});
}

// function 3 - will be wrapped in a resolved promise by .then()
function f3(a) {
return a * 3;
}

// promise function 4
function p4(a) {
return new Promise((resolve, reject) => {
resolve(a * 4);
});
}

const promiseArr = [p1, p2, f3, p4];
run(promiseArr, 10).then(console.log);
  1. 函数 1 调用函数 2,如果想在函数 2 里终止函数 1,如何操作?
1
2
3
4
5
6
7
8
9
10
11
12
function a() {
b();
if (b === 3) {
return;
}
console.log("a");
}
function b() {
console.log("b");
return (b = 2);
}
a();
  1. 用闭包实现 localStorage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function configCache(){
let _cache = new Map()
return {
getCache(k){
return _cache[k]
},
setCache(k, v){
_cache[k] = v
return this
},
removeCache(k){
delete _cache[k];
return this
}
}
}();

  1. 用 setTimeout 实现 setInterval

setTimeout 只执行一次.
setinterval 是定时执行多次

1
2
3
4
5
6
7
function interval(fn, ms) {
let set = () => {
setTimeout(set, ms);
fn();
};
setTimeout(set, ms);
}
  1. 写一个函数拍平.禁止用 float

遍历传入数组,如果某一元素是数组,那就取出,放入原数组.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//递归
function flat(arr) {
let res = [];
let each = function (arr) {
arr.forEach((item) => {
if (item instanceof Array) {
each(item);
} else {
res.push(item);
}
});
};
each(arr);
return res;
}
let a = [1, [2, 3], [6, [5, 7]], 4];
console.log(flat(a));
//使用reduce
function flat(arr) {
return arr.reduce((a, b) => {
return Array.isArray(b) ? [...a, ...flat(b)] : [...a, b];
}, []);
}
let arr = [1, [2, 3], [6, [5, 7]], 4];
console.log(flat(arr)); // [1, 2, 3, 6, [5, 7], 4],

//转化字符串toString
function flat(arr) {
return arr
.toString()
.split(",")
.map((item) => +item);
}
let arr = [1, [2, 3], [6, [5, 7]], 4];
console.log(flat(arr));

小明机选题