这里记录一些常见的面试题
call的简单实现
function fn (a, b, c) {
console.log(this)
return a + b + c
}
const obj = {
name: 'xxx'
}
// fn.call(obj, 1,2,3)
Function.prototype.mycall = function (context, ...args) {
context = context || window
// obj.fn()
// context.fn = this
Object.defineProperty(context, 'fn', {
value: this,
enumerable: false,
configurable: true
})
// console.log(Object.getOwnPropertyDescriptor(context, 'fn'))
const result = context.fn(...args)
delete context.fn
return result
}
fn.mycall(obj, 1, 2, 3)
console.log(obj)
改变this解题思路:给绑定的this对象通过defineProperty添加一个回调fn不可枚举的属性,这样传入的this对象上看不到它,值就是当前的this,也就是要调用mycall的函数(例子中的this就是函数fn) ,然后通过对象.调用的方式来调用绑定this对象上的我们定义的函数,通过这种方式来变相的确定内部的this,最后再删除掉我们之前定义在传入的绑定this对象上的fn,最后返回 函数调用的结果.
滴滴面试题
1. 说⼀下js的数据类型,如何判断数据类型
Number String Object Null Undefined Boolean Symbol
第一种typeof,在这个方法的问题是 判断Object的时候,无法精确判断object还是array还是date等i、引用类型,判断null时会返回'object',判断function会返回'function',排除这些 其他的是可以正常返回的,它的一个好处是判断为定义的变量不会报错,而是返回'undefined'
第二种instanceof,instanceof 是用来判断 A 是否为 B 的实例,表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。 在这里需要特别注意的是:instanceof 检测的是原型
[]的原型指向Array.prototype,间接指向Object.prototype, 因此 [] instanceof Array 返回true, [] instanceof Object 也返回true。
instanceof 只能用来判断两个对象是否属于实例关系, 而不能判断一个对象实例具体属于哪种类型。
最后就是tostring,toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。
对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。
例如:
Object.prototype.toString.call('') ; // [object String]
Object.prototype.toString.call(1) ; // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(Symbol()); //[object Symbol]
Object.prototype.toString.call(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; //[object global] window 是全局对象 global 的引用
综上所述 第三种方式最好
2.说⼀下防抖函数的应⽤场景,并简单说下实现⽅式
function throttle(cb, time) {
let timer;
return function (...args) {
let ctx = this;
if (timer) { clearTimeout(timer); }
timer = setTimeout(() => {
cb.apply(ctx, args);
}, time);
}
}
应用场景主要用于: 输入框值变化下拉请求,元素大小变化事件,手机移动端下拉加载,一般用于防止方法频繁触发,取指定时间段的最后一次触发。
3.new Promise构造函数的⼊参是什么?你在什么场景下会使⽤promise
构造函数 入参是一个函数,这个函数 传入是会立即执行的。这个入参 函数是同步执行的resolve之后then里的会产生微任务。 正常情况请求 是promise 还有就是想在本轮宏任务 最后开始执行,可以使用promsie加入微任务队列,主要场景是在不阻塞主线程的情况,并且想尽快展示到界面会使用promsie,例如vue源码中的 nextTick。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。