前端面试JS相关

什么是原型?原型链

每个对象都有原型,对象的原型可以通过其构造函数的 prototype 属性访问。查找㇐个对象的属性或⽅法时,
如果在对象本身上没有,就会去其原型上查找;
⽽原型本身也是㇐个对象,如果在
原型上也找不到,就会继续找原型的原型, 原型链的终点是null

什么是闭包

内部函数 inner 如果引⽤了外部函数 outer 的变量 a,会形成闭包。如果这个内部函数作为外部函数的返回值,就会形成词法环境的引⽤闭环(循环引⽤),对
应变量 a 就会常驻在内存中,形成⼤家所说的“闭包内存泄漏”。虽然闭包有内存上的问题,但是却突破了函数作⽤域的限制,使函数内外搭起了沟通的桥
梁。闭包也是实现私有⽅法或属性,暴露部分公共⽅法的渠道。还可以引申出柯⾥化,bind 等概念,⾯试官说“可以啊,⼩伙⼦!” 变量提升问题
JS 分为词法分析阶段和代码执⾏阶段。在词法分析阶段,变量和函数会被提升(Hoist),注意 let 和 const 不会提升。⽽赋值操作以及函数表达式是不会被提
升的。 
出现变量声明和函数声明重名的情况时,函数声明优先级⾼,会覆盖掉同名的变量声明!为了降低出错的⻛险,尽量避免使⽤hoist!
简单来说就是 函数内部访问函数外部的变量
var obj = {
val: 5
}
function test(obj) {
 
obj.val = 10;
 
console.log(obj.val);
 
var obj = { val: 20 };
 
console.log(obj.val)
}
test(obj);
console.log(obj.val)
// 10 20 10


JS中的this

如果是在全局作⽤域下,this 的值是全局对象,浏览器环境下是 window。
函数中 this 的指向取决于函数的调⽤形式,在㇐些情况下也受到严格模式的影响。
●作为普通函数调⽤:严格模式下,this 的值是 undefined,⾮严格模式下,this 指向全局对象。 
● 作为⽅法调⽤:this 指向所属对象。 
● 作为构造函数调⽤:this 指向实例化的对象。 
● 通过 call, apply, bind 调⽤:如果指定了第㇐个参数 thisArg,this 的值就是 thisArg 的值(如果是原始值,会包装为对象);如果不传 thisArg,要判断
严格模式,严格模式下 this 是 undefined,⾮严格模式下 this 指向全局对象。

继承

  • 通过原型链实现继承
// 定义一个动物类
function Animal (name) {
  // 属性
  this.name = name || 'Animal';
  // 实例方法
  this.sleep = function(){
    console.log(this.name + '正在睡觉!');
  }
}
// 原型方法
Animal.prototype.eat = function(food) {
  console.log(this.name + '正在吃:' + food);
};
  • 核心: 将父类的实例作为子类的原型
function Cat(){ 
}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.eat('fish'));
console.log(cat.sleep());
console.log(cat instanceof Animal); //true 
console.log(cat instanceof Cat); //true

特点:

  • 非常纯粹的继承关系,实例是子类的实例,也是父类的实例

  • 父类新增原型方法/原型属性,子类都能访问到

  • 简单,易于实现

2构造继承

核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)

function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true

缺点

  • 只能继承父类的实例属性和方法,不能继承原型属性/方法
  • 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
  • 实例并不是父类的实例,只是子类的实例

3实例继承

核心:为父类实例添加新特性,作为子类实例返回

function Cat(name){
  var instance = new Animal();
  instance.name = name || 'Tom';
  return instance;
}

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // false

特点

  • 不限制调用方式,不管是new 子类()还是子类(),返回的对象具有相同的效果
  • 实例是父类的实例,不是子类的实例
  • 不支持多继承

节流防抖

防抖
抖的意思是,在连续的操作中,无论进行了多长时间,只有某一次的操作后在指定的时间内没有再操作,这一次才被判定有效。具体场景可以搜索框输入关键字过程中实时 请求服务器匹配搜索结果,如果不进行处理,那么就是输入框内容一直变化,导致一直发送请求。如果进行防抖处理,结果就是当我们输入内容完成后,一定时间(比如500ms)没有再 输入内容,这时再触发请求。
应⽤场景:

  1. 窗⼝⼤⼩变化,调整样式
  2. 搜索框,输⼊后 1000 毫秒搜索
  3. 表单验证,输⼊1000 毫秒后验证
  4. 频繁点击按钮,使⽤防抖避免重复提交请求
function debounce(handler,ms,flag){
let timer = null;
 
return function(...args){
 
clearTimeout(timer);
 
if(flag&&!timer){
 
handler.apply(this,args);
 
}
 
timer = setTimeout(()=>{
 
handler.apply(this,args);
 
},ms)
 
}
}
//demo
window.addEventListener('resize',debounce(handler,1000));
function handler(){
 
console.log('ok');
}

节流
节流( throttle ):节流的意思是,规定时间内,只触发一次。比如我们设定500ms,在这个时间内,无论点击按钮多少次,它都只会触发一次。具体场景可以是抢购时候,由于有无数人 快速点击按钮,如果每次点击都发送请求,就会给服务器造成巨大的压力,但是我们进行节流后,就会大大减少请求的次数。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

初遇你时动了情

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值