前端面经
- js 数据类型有哪些
数据类型:Number,Object,String,Null,Undefined,Boolean,Symbol
- null 和 undefined 的区别
null表示没有对象,即该处不应该有值 undefined表示缺少值,即此处应该有值
- js 判断数据类型的方法
typeof,instanceof.Object.prototype.toString.call(),其中 typeof无法判断类型是数组还是object,返回的都是 object类型,不能准确定位其类型。instanceof能后判断数据类型,但是其类型是基于对象object的。 Object.prototype.toString.call()返回[object,type]
- 什么是原型链
任何一个类(函数)都有一个原型对象,原型对象至少有两个属性对象(constructor,prototype),其中constructor
指向函数本身,proptotype指向父原型对象,函数的实例可以直接访问原型对象,因为实例上__proto__指向构
造函数的原型对象
手写 call,apply,bind
call 和 apply 的实现思路主要是,首先判断是否是函数调用,如果不是直接抛异常,通过新对象 context 来调用函数,
给 context 创建一个 fn 设置为需要调用的函数,结束调用完成后删除 fn。
bind 实现: 判断是否函数调用,不是直接抛出异常,返回函数:判断函数的调用方式,是否被 new 出来的,如果是 new 出来的直接返回空对象,但是实例的__proto__
指向_this
的prototype
,最后完成函数柯里化 `Array.prototype.slice.call()
call:
Function.prototype.mycall = function(context){
if(typeof this !== 'function'){
throw new TypeError('not a function')
}
context = context || window
context.fn = this
//保存参数
let args = Array.from(arguments).slice(1)
//调用函数
let result = context.fn(...args)
delete context.fn
return result
}
apply 实现
Function.prototype.maApply = function(context){
if(typeof this !== 'function'){
throw new TypeError('not a function')
}
let result
context = context || window
//保存this
context.fn = this
if(arguments[1]){
result = context.fn(...arguments[1])
}else{
result = context.fn()
}
delete context.fn
return result
}
bind 实现
Function.prototype.myBind = function(context){
if(typeof this !== 'function'){
throw new TypeError('not a function')
}
//保存调用bind的函数
const _this = this
//保存参数
const args = Array.prototype.slice.call(arguments,1)
//返回一个整数
return function F(){
if(this instanceof F){
//是new出来的 返回一个空对象,且使创建出来的实例的__proto__指向_this的prototype, 且完成函数柯里化
return new _this(...args,...arguments)
}else{
//如果不是new出来的改变this的指向,完成柯里化
return _this.apply(context,args.concat(...arguments))
}
}
}
new 的实现
function myNew(fn,...args){
//创建一个空对象
let obj = {}
//使空对象的隐式原型指向原函数的显示原型
obj.__proto__ = fn.prototype
//this指向obj
let result = fn.apply(obj,args)
return result instanceof Object ? result : obj
}
深拷贝
function isObject(o){
return Object.prototype.toString.call(o) === "[object Object]" || Object.prototype.toString.call(o) === "[object Array]"
}
function deepClone(o,hash=new map()){
if(!isObject(o)) return o
if(hash.has(o)) return hash.get(o)
let obj = Array.isArray(o)?[]:{}
hash.set(o,obj)
for(let i in o){
if(isObject(o[i])){
obj[i] = deepClone(o[i],hash)
}else{
obj[i] = o[i]
}
}
return obj
}
网友评论