20道大厂面试
- New 的实现原理:
- 实例化一个新对象,添加新对象方法和属性;继承原型链;
- 正确判断this的指向:
- 正常:谁调用this就指向谁;
- 技巧:
- 全局环境中的this;this=window;
- 是否是 new绑定;指向新对象:function Super(age){this.age=age};let xx=new Super('26');xxx.age//26
- function Super(age){this.age=age;let obj={a:2}return obj};let xx=new Super('26');xxx.age//undefined//{a:1}
- (显示绑定)函数是否通过call apply bind绑定;指向绑定对象;.bind(thisArg,)()
- 隐式绑定;谁调用this就指向谁
- 默认绑定:谁调用this就指向谁
- 箭头函数:看上下文绑定,谁调用this就指向谁
- Const fn={
num:10;
aaa(){
return this.num*2
},
bbb()=>this.num*4//指向window
};
Fn.aaa();//20
Fn.bbb();//NaN;
================================
Obj.fn{…..}//指向obj
- 深拷贝和浅拷贝区别?实现一个深拷贝:
- 深拷贝和浅拷贝针对复杂的数据类型来说的。浅拷贝只拷贝一层,而深拷贝是层层拷贝。
- 深拷贝:复制变量值,对于非基本类型的变量,则递归至基本类型变量后,在复制。深拷贝后的对象与原来对象完全隔离互不影响,一个对象修改并不会影响到另一对象;
- Json.parse(json.stringify(obj))//属性值非函数;不能拷贝原型链上的属性;忽略symbol和undefinen;
- 实现一个deepClone函数:
- 如果是基本数据类型,直接返回;
- 如果是regExp或者Date类型,返回对应类型;
- 如果是复杂数据类型,递归;
Function deepClone(obj1,hash=new WeakMap()){
if(obj1 instanceof RegExp) return new regExp(obj1);
if(obj1 instanceof Date)return new Date(obj1);
if(obj1===null||typeof obj1!=='object'){return obj1};
let t=new obj1.constructor();
hash.set(obj,t);
for(let key in obj1){
if(obj1.hasownproperty(key)){t[key]=deepClone(obj1[key],hash)}
}
}
- 浅拷贝:将对象的每个属性进行依次复制,但是当对象的属性值是引用类型时,实际复制的是其引用,当引用指向的值改变时也会跟着改变。
- For in
- Let obj2=Object.Assign({},obj1);
- Let obj2=object.create(obj1)
- Let obj3={…obj1};
- Call/apply实现原理:
- 都是改变this的指向,并且立即执行,只不过传参不同。
- .call(thisArg,arg1,arg2,arg3);原理:
- 依赖函数原型上的方法call()
- 如果第一个参数不传,默认指向window;传入则thisArg.func(){}//obj.foo(this.指向obj);
- .apply(thisArg,[args]);原理:雷同.call
- 柯里化函数实现:
- 把接收多个参数的函数变换成接受一个单一参数的函数,并且返回接受余下的参数而且返回结果的新函数的技术。?????Add(1,2,3,4)=>add(1)(2)(3)(4)
一种设计思想,主动掌握函数的控制权,根据我们的需要设计相应的触发机制(函数生成函数,函数去调F函数)
- 如何实现(a==1&&a==2&&c==3)都为true:
- 利用数据劫持es6新增了 proxy
let a=new proxy(){
i:1,
get:function(){return ()=>this.i++};
}; - 数组的toString接口默认调用数组的join方法,重写join方法:
Let a=[1,2,3];
a.join=a,shift;
- 对象object转为原始类型的调用方法:
- 先看是否部署 [symbol.toPrimitive];
- 否:根据转换的类型,先调用valueof/tostring
- Var obj={
[symbol.toprimitive](){return 1},
valueOf(){return 2},
toString(){return 3}
}
- 什么是BFC?规则?如何创建BFC?
- Box formatting context:
- 异步加载Js脚本的方式有哪些?
- <script>新增了async(h5)或defer(h4)属性,脚本就会异步加载;
- Defer在window.onload之前执行;
- async一旦下载渲染引擎就会中断渲染,执行这个脚本后在继续渲染;
- 动态加载<script>:
Let script=document.createElement('script');
Script.src='xxx.js';
Document.body.append(script);
- Es5有几种方式可以实现继承?
- 原型链继承:原型链的继承思想是利用原型让一个引用类型继承里一个引用类型的属性和方法;
Function SuperType(){
This.name='kk'
}
superType.protoType.getName=function(){
Return this.name
}
Let sss=new superType();
Sss.getName();//kk
- 借用构造函数:
- 原型链+构造函数
- 原型式继承;
- Es5的object.create()方法
var person={
Name:'kk'
};
var p2=object.create(person);
P2.name='xxx';
- 寄生式继承;
- For in:
Function Cat(name){
var animal=newAnimal();
for (var p in animal){
cat.prototype[p]=animal[p]
}
cat.prototype.name=name||'jack'
}
- 寄生组合式继承;
- Function Cat(name){
Animal.call(this,name)//劫持其他对象
}
- 隐藏页面中的某个元素的方法有哪些?
- Display:none;
- Visibility:hidden;
- Overflow:hidden;
- Opacity:0
- Display:absolute z-index-9999;//relative:left:-999
- Transform:scle(0);height:0(缩放);rotateY(90deg)(旋转);transform:translateX(-9999px)(移动);
- Let const var 区别?
- Var 变量提升,允许重复声明;let const不提升,同作用域内也不允许重复声明;
- Const 是定义只读常量,不可修改(栈中存的只是地址指针);
- Let for块作用域
- 说说你对Js执行上下文栈和作用域链的理解?
- 栈:
- 全局作用域;块作用域(for);函数作用域(function)
- 防抖函数的作用是什么?
- 防抖函数:控制函数在一定时间内的执行次数。防抖意味n秒内函数只能执行一次,如果内秒内再触发则重新计时;手机验证码,输入框实时搜索; 公交车一直上人刷卡,最后一次才走(减肥10天不吃奖励,中间吃了重新计算时间);
- 节流函数,有哪些应用场景,请实现一个节流函数:
- 节流函数:规定一定时间内只能触发一次函数执行;提交按钮事件;推拽事件;一定时间内人眨一次眼睛(减肥不管中间10天吃没吃,都要买一包)。
- 什么是闭包?闭包的作用?
- 解释:有权限访问另一个函数作用域中变量的函数;
- Function fn(){ var a=1;return function(){return console.log(a)} };let foo=fn;foo()//1
- 实现promise.all方法:
- Let p=Promise.all([p1,p2,p3]);//都成功p才fulilled/resolve,否则rejected
- 请实现一个flattendeep函数,把嵌套的数据扁平化:
- 数据扁平化:多维数组,拉平一层,2维变1维数组;
利用ES6:数组新方法 arr.flat(arr,deeplength);//不参deeplength默认一层; - 请实现一个uniq函数,实现数组去重:
- 方法1:遍历;判断(!Arr[i]);push新数组;
- 方法2:遍历;判断newArr.indexOf(Arr[i])===-1;
- 方法3:ES6,新的数据类型 set:类似数组,但元素都是不重复的:return […new Set(Arr)]//拷贝
- 方法4:遍历;判断!newArr.includes(Arr[i]);
- 方法5:map.has(arr[i]);
- 方法6:reduce??
- 可迭代对象有那些特点:es6规定:具有symbol.itetaor属性就可以认为是迭代的。
- jsop的原理:
利用<script >的src属性不会被浏览器的同源策略所约束,获取任意服务器上的脚本。
参数只能通过url传入,仅支持get请求。
原理:callback方法;插入<script>标签;后台返回数据
参考:nigx后台设置;CORS:跨域资源共享,允许浏览器跨域