# 名媛云万年面试题
# 1. this 输出值
// This 对象的理解
var User = {
count:1,
getCount:function(){
return this.count;
}
}
console.log(User.getCount());
var func = User.getCount;
console.log(func());
// 1, undefined
# 2.
# 3. 跨域
如何解决跨域问题?
# 4. 浏览器缓存
如何设置浏览器缓存与不缓存两种。
# 5. 深拷贝
实现一个函数clone,可以对JavaScript中的5种主要数据类型进行值复制
function deepClone(target) {
// is Object???
if (typeof target == "object") {
// array or object
const result = Array.isArray(target) ? [] : {}
for (let key in target) {
if (target.hasOwnProperty(key)) {
// 引用类型需要再次递归
result[key] = typeof target[key] == "object" ? deepClone(target[key]) : target[key]
}
}
return result
}
return target
}
# 6. 多层ID提取
代码实现(有几种实现)
var arr = [
{
id:1,
children:[...] | null
},
...
]
变量arr是一个object数组,数组元素为object,有2个属性
id:数字类型
children:有两种类型,一种是数组,结构类似于变量arr;一种是null
请用代码实现从变量arr中提取出孙子元素的id组成一个一维数组,如[1,2,3,...]
- 循环
function getArr(arr) {
const result = []
if (arr && Array.isArray(arr)) {
for (const i in arr) {
// 第一层id
result.push(arr[i].id)
let children = arr[i].children
let queue = []
if (children) {
queue.push(children)
}
let queueItem = queue.shift()
while (queueItem) {
queueItem.forEach(item => {
result.push(item.id)
if (item.children) {
queue.push(item.children)
}
})
queueItem = queue.shift()
}
}
}
return result
}
- 递归
function getArr2(arr) {
const result = []
if (arr && Array.isArray(arr)) {
(function rec(argsArr){
argsArr.forEach(item => {
result.push(item.id)
let children = item.children
if (children && Array.isArray(children)) {
rec(children)
}
})
})(arr)
}
return result
}
# 7. 数组范围求和
不可变数组的范围求和
给定一个整数数组nums,计算出从i个元素到第j个元素的和(i<=j),包括nums[i]和nums[j].
例子:
const nums = Object.freeze([-2,0,3,-5,2,-1]);
sumRange(0,2) // 1
sumRange(2,5) // -1
sumRange(0,5) // -3
注意:
假定数组的值不会改变(如上面代码,nums因为Object.freeze的缘故可读不可写)
sumRange可能会被使用多次,求不同范围的值
数组规模可能很大(比如超过10000个数),注意运行时间
function sumRange(i, j) {
const sums = []
sums[0] = 0
nums.forEach((item, i) => {
sums[i + 1] = sums[i] + item
})
return sums[j + 1] - sums[i]
}
# 8. LazyMan实现
实现一个LazyMan,可以按照以下方式调用
LazyMan("Hank") 输出
Hi!This is Hank!
LazyMan("Hank").sleep(10).eat("dinner"); 输出
Hi! This is Hank!
// 等待10秒...
Wake up after 10
Eat dinner~
LazyMan("Hank").eat("dinner").eat("supper") 输出
Hi This is Hank!
Eat dinner~
Eat supper~
LazyMan("Hank").sleepFirst(5).eat("supper") 输出
// 等待5秒
Wake up after 5
Hi This is Hank!
Eat supper
以此类推
- Promise + setTimeout 解法
class LazyMan {
constructor(name) {
this.name = name;
this.presetTime = 0;
this.p = Promise.resolve().then(() => {
// sleepFirst 延迟所有操作
if(this.presetTime > 0) {
return this.holdon(this.presetTime);
}
}).then(() => {
this.sayName()
})
}
sayName() {
console.log(`Hi! This is ${this.name}`)
return this
}
sleep(time) {
this.p = this.p.then(() => {
return this.holdon(time)
})
return this
}
eat(food) {
this.p = this.p.then(() => {
console.log(`Eat, ${food}`)
})
return this
}
holdon(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(`Wake up after ${time}`)
resolve()
}, time * 1000)
})
}
sleepFirst(time) {
this.presetTime = time
return this
}
}