likes
comments
collection
share

大厂面经 - 聊聊经常被面试官问到的原型链

作者站长头像
站长
· 阅读数 4

1. 前言

无意看到了之前整理的高频面试笔记,发现很多都有点陌生了,之后我有时间会陆续把一些比较重要的前端知识更新出来

尤其是现在就业环境不太好的情况下,一方面自己复习巩固下防患于未然,一方面也给小伙伴们的面试助一把力啦

这期依旧是之前整理的高频面试笔记中的题目

大厂面经 - 聊聊经常被面试官问到的原型链

2. 普通函数和构造函数有什么区别

这一直是我新手期比较困惑的问题,网上说这个的版本很多,但是都没有让我印象深刻。直到最近翻之前的笔记,好像豁然开朗啦~~~

构造函数是函数的其中一种用法,它们的用途不同

function test(){}
function Test(){}
let a = new Test()
console.log(test, Test, a)

大厂面经 - 聊聊经常被面试官问到的原型链

大家可以看下上图

其实两者的明显区别只有两个

  • 用法:被new了之后的是构造函数(构造函数的命名规范是首字母大写)

  • this指向:

    • 构造函数中this指向新创建的对象实例

    • 普通函数中this指向取决于函数的调用方式

构造函数

function Person(name, age) {
  // 实例属性
  this.age = age;

  // 实例方法
  this.sayHello = function() {
    console.log(111);
  };
}

// 创建对象实例 
const person1 = new Person('Alice', 30);

// 调用实例方法
person1.sayHello();

普通函数

// 普通函数
function greet(name) {
  console.log(`Hello, ${name}!`);
}

// 调用普通函数
greet('Alice'); // 输出:Hello, Alice!

3. prototype

每个函数都有一个prototype

function Person() {
}
// prototype是函数才会有的属性
Person.prototype.name = 'cluonote';
var person1 = new Person();
console.log(person1)

大厂面经 - 聊聊经常被面试官问到的原型链

这里,Person 就是⼀个构造函数,我们使⽤ new 创建了⼀个实例对象 person1

那这个函数的prototype 指向的是什么呢?

通俗的说:new 构造函数生成实例的时候,把该构造函数的prototype放到了实例的原型上

通俗的说:该函数的 prototype指向的是实例的原型,也就是person1的原型Person.prototype(不是person1.prototype,见下图),也就是person1.__protoo__见下文

大厂面经 - 聊聊经常被面试官问到的原型链

那什么是原型呢?

每个对象(null除外)在创建的时候就会与之关联另⼀个对象,这个对象就是我们所说的原型,每⼀个对象都会从原型"继承"属性。

4. __proto__

那么该怎么表示实例与实例原型,也就是 person 和 Person. prototype 之间的关系呢?

使用__proto__来表示

这是每⼀个对象(除了 null )都具有的⼀个属性,叫 __proto__ ,这个属性会指向该对象的原型。


function Person() {
}
var person = new Person();
console.log(person.__proto__ === Person.prototype); // true

5. constructor

既然实例对象和构造函数都可以指向原型,那么原型是否有属性指向构造函数或者实例呢

上面这句话划重点了,有点对知识体系承上启下的意思

指向实例没有,因为⼀个构造函数可以⽣成多个实例,但是原型指向构造函数是有的constructor ,每个原型都有⼀个 constructor 属性指向关联的构造函数

function Person() {
}
console.log(Person === Person.prototype.constructor); // true

6. 原型链

当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,⼀直找到最顶层为⽌。

大厂面经 - 聊聊经常被面试官问到的原型链

function Person() {
    this.age = '18'
}
// prototype是函数才会有的属性
Person.prototype.age = '8';
var person1 = new Person();
console.log(person1)

我们要是找age的值,首先会到person1.age(18),假如找不到,会找person1.__proto__.age(8),假如还找不到,会找Person.prototype.__proto__.age,假如还找不到,会找Object.prototype.__proto__.age

找到Object.prototype.__proto__会发现是null,就会停止查找了,这是最顶层

person1.__proto__ 等于 Person.prototype

Person.prototype.__proto__ 等于 Object.prototype

如下图,蓝色的就是原型链

大厂面经 - 聊聊经常被面试官问到的原型链

7. 面试

7.1 说说原型链是什么吧

原型链里面涉及到以下几个知识点:构造函数、prototype__proto__constructor和向上溯源

  • 每个函数都有一个prototype

  • 构造函数的原型指向该构造函数的实例对象的原型,反过来也OK,构造函数的实例的原型等于该构造函数的原型

function Person() { } 
var person = new Person(); 
console.log(person.__proto__ === Person.prototype); // true
  • 礼尚往来,构造函数和实例对象都可以指向原型,那么原型的constructor指向哪里呢?指向其构造函数

  • 而原型链:就是找实例对象的属性,如果找不到就去找实例对象的原型里找,再找不到,就去找原型的原型,⼀直找到最顶层为⽌。

  • 原型链的顶层Object.prototype.__proto__,为null

7.2 类的实例对象的__proto__ === 类的原型吗

等于的

console.log(person.__proto__ === Person.prototype); // true

7.3 类本身 === 类的原型的构造函数吗

等于的

function Person() { } 
console.log(Person === Person.prototype.constructor); // true

参考资料:

JavaScript深入之从原型到原型链

9. 总结

原型链算是一个内功心法,工作中常有用到。

其实搞清楚其几个核心概念:构造函数、prototype__proto__constructor和向上溯源,基本就算拿下了

这篇文章我尽力把我的笔记和想法放到这了,希望对小伙伴有帮助。

欢迎转载,但请注明来源。 最后,希望小伙伴们给我个免费的点赞,祝大家心想事成,平安喜乐。

大厂面经 - 聊聊经常被面试官问到的原型链

转载自:https://juejin.cn/post/7350602010906083328
评论
请登录