前端面试题高概率问题总结

1.this指向问题,es5和es6有什么区别呢?

答:
1)在es5中,始终要坚持一个原理:this永远指向最后调用它的那个对象,this永远指向最后调用它的那个对象,this永远指向最后调用它的那个对象。
2)在es6中,箭头函数是可以避免es5中使用的这个坑的。箭头函数的this始终指向函数定义时的this,而非执行时。箭头函数需要记着这句话:“箭头函数中没有 this 绑定,必须通过查找 作用域链 来决定其值,如果箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this,否则,this 为 undefined”。
3)再加一句:匿名函数的 this 永远指向 window。

2.如何改变this的指向?

答:1)使用箭头函数;2)在函数内部使用 var _this=this 将this赋值给变量,然后在内部使用_this 调用对象的属性;3)apply,call,bind函数。

3.apply,call,bind的区别?

答:这三个函数都是用来改变this指向的,例如:

let a = {
    value: 1
}
function getValue(name, age) {
   var value=5;
    console.log(name);
    console.log(age);
   console.log(this);
    console.log(this.value)
}

getValue('zhang',22);   //    zhang, 22 , window , undifined ;
getValue.call(a, 'yck', '24')  //yck , 24 ,  a , 1
getValue.apply(a, ['yck', '24'])  //yck , 24 ,  a , 1
var fn = getValue.bind(a,'yck','24');  
fn();   //yck , 24 ,  a , 1

调用的方式不同,第一个参数都是要绑定的对象,除去第一个参数,call和bind 可以接收一个参数列表,apply 只接受一个参数数组。
返回类型不同,call和apply直接调用;bind返回一个function,需要调用执行。

4.简单说一下原型链?

答:1)每个函数都有 prototype 属性,除了 Function.prototype.bind(),该属性指向原型。
2)每个对象都有 _ proto _ 属性,指向了创建该对象的构造函数的原型。其实这个属性指向了 [[prototype]],但是 [[prototype]]是内部属性,我们并不能访问到,所以使用 proto来访问。
3)对象可以通过 _ proto _ 来寻找不属于该对象的属性,_ proto _ 将对象连接起来组成了原型链。

5.为什么要使用闭包?

答:1)为了读取函数内部的变量;2)将创建的变量的值始终保持在内存中,以供本地环境使用。

6.javascript如何做继承?

答:
1)es5中通过prototype,将子类的原型设置成父类

function Super() {}
Super.prototype.getNumber = function() {
  return 1
}

function Sub() {}
let s = new Sub()
Sub.prototype = Object.create(Super.prototype, {
  constructor: {
    value: Sub,
    enumerable: false,
    writable: true,
    configurable: true
  }
})

2)es6中,通过class 语法轻松解决这个问题

class MyDate extends Date {
  test() {
    return this.getTime()
  }
}
let myDate = new MyDate()
myDate.test()

但是 ES6 不是所有浏览器都兼容,所以我们需要使用 Babel 来编译这段代码。
如果你使用编译过得代码调用 myDate.test()你会惊奇地发现出现了报错

因为在 JS 底层有限制,如果不是由 Date构造出来的实例的话,是不能调用 Date 里的函数的。所以这也侧面的说明了:ES6 中的 class 继承与 ES5 中的一般继承写法是不同的。

既然底层限制了实例必须由 Date 构造出来,那么我们可以改变下思路实现继承

function MyData() {

}
MyData.prototype.test = function () {
  return this.getTime()
}
let d = new Date()
Object.setPrototypeOf(d, MyData.prototype)
Object.setPrototypeOf(MyData.prototype, Date.prototype)

以上继承实现思路:先创建父类实例 => 改变实例原先的 proto_转而连接到子类的 prototype=> 子类的 prototype 的 proto 改为父类的 prototype。
通过以上方法实现的继承就可以完美解决 JS 底层的这个限制

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 特别说明,为便于查阅,文章转自https://github.com/getify/You-Dont-Know-JS...
    杀破狼real阅读 4,860评论 0 4
  • 函数和对象 1、函数 1.1 函数概述 函数对于任何一门语言来说都是核心的概念。通过函数可以封装任意多条语句,而且...
    道无虚阅读 10,180评论 0 5
  • 第一章 错误处理: 错误: 程序运行过程中,导致程序无法正常执行的现象(即bug) 现象: 程序一旦出错,默认会报...
    fastwe阅读 4,887评论 0 1
  • 前言 面试官出很多考题,基本都会变着方式来考察this指向,看候选人对JS基础知识是否扎实。读者可以先拉到底部看总...
    若川i阅读 4,803评论 0 10
  • “哎,你们说咱们府里这位,整天都病殃殃的,多晦气啊,也难怪少爷老是往陈府跑,要我说……”“闭嘴!主子也是你们能置噱...
    莫浅漓阅读 1,738评论 2 4

友情链接更多精彩内容