您的位置:

深入解析JavaScript原型链面试题

JavaScript 是一种弱类型、基于原型的编程语言。原型是 JavaScript 的一项非常重要的特性,也是面试中经常考察的知识点。JS 原型链是基于原型的面向对象编程的基石,掌握这一知识点对于我们理解 JavaScript 的对象模型非常重要。本文将带你从多个方面深入剖析JavaScript原型链面试题。

一、JS原型链基本概念

在 JavaScript 中,每个函数都有一个 prototype 属性,也就是原型对象。原型对象是一个普通的对象,包含属性和方法。每个实例对象都通过 __proto__ 属性引用其构造函数的原型对象 prototype。

function Person(name, age) {
  this.name = name;
  this.age = age;
}
Person.prototype.sayHello = function() {
  console.log(`Hello, I'm ${this.name}, I'm ${this.age} years old.`);
}
const person = new Person('Tom', 18);

在以上代码中,Person 函数有一个 prototype 属性,它是一个普通的对象,并且包含一个方法 sayHello。person 是使用 Person 函数构造出来的实例对象, 它通过 __proto__ 属性引用了 Person 的原型对象 Person.prototype,因此它可以使用原型对象中的方法 sayHello。

二、JS原型链的构建方式

原型链是由每个对象的 __proto__ 属性构成的。我们可以通过以下方式构建原型链:

1. 新建一个构造器函数

2. 扩展构造器的原型对象

3. 使用 new 操作符创建子对象

4. 构造器原型对象的 __proto__ 属性指向构造器父级的原型对象

5. 子对象的 __proto__ 属性指向了构造器的原型对象,也就是形成了原型链

function Animal(name) {
  this.name = name;
}
Animal.prototype.sayName = function () {
  console.log(this.name);
}

function Dog(name, age) {
  this.age = age;
  Animal.call(this, name);
}
Dog.prototype = Object.create(Animal.prototype); // Dog 继承 Animal 
Dog.prototype.constructor = Dog; // constructor 指向 Dog 
Dog.prototype.sayAge = function () {
  console.log(this.age);
}

const dog = new Dog('Lily', 1);

在以上代码中,Dog 继承了 Animal 的方法以及属性。通过 Dog.prototype = Object.create(Animal.prototype),Dog 的原型指向了 Animal 的原型,因此它可以使用 Animal 的原型中的方法 sayName,在 Dog 的原型中添加 sayAge 方法。

三、JS原型链的查找顺序

当我们在一个实例对象上调用一个属性或者方法时,JavaScript 引擎会按照如下的顺序查找属性或方法:

1. 首先查找实例对象本身是否有该属性或方法

2. 如果没有,则查找实例对象的原型对象是否有该属性或方法

3. 如果还没有,则查找实例对象原型对象的原型对象是否有该属性或方法

4. 重复上述步骤,直到查找到 Object 的原型对象,即可结束查找

function Animal(name) {
  this.name = name;
}
Animal.prototype.sayName = function () {
  console.log(this.name);
}

function Dog(name, age) {
  this.age = age;
  Animal.call(this, name);
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.sayAge = function () {
  console.log(this.age);
}

const dog = new Dog('Lily', 1);
console.log(dog.__proto__ === Dog.prototype); // true
console.log(Dog.prototype.__proto__ === Animal.prototype); // true
console.log(Animal.prototype.__proto__ === Object.prototype); // true

在以上代码中,dog 是 Dog 的实例对象。当我们在 dog 上调用 sayAge 方法时,首先查找 dog 本身是否有该方法,发现没有。然后查找 Dog.prototype 是否有该方法,发现有。因此调用了该方法并输出了 dog 的年龄。在这个查找的过程中,JS 引擎按照 __proto__ 属性指向的原型对象继续查找,直到最后找到 Object 的原型对象 Object.prototype 为止。

四、JS原型链的继承方式

在 JavaScript 中,有很多实现继承的方法。下面分别介绍一下常用的几种继承方式:

1. 构造函数继承

构造函数继承是一种常用的继承方式。其基本思想是在子类的构造函数中调用父类的构造函数。

function Parent(age) {
  this.age = age;
}
function Child(age) {
  Parent.call(this, age);
}
const child = new Child(18);
console.log(child.age); // 18

在以上代码中,Child 函数的构造函数中调用了 Parent 的构造函数并传入参数。Child 实例可以访问到 Parent 实例中的属性 age。

2. 原型链继承

原型链继承的基本思想是通过将子类的原型对象指向父类的实例对象来实现继承。

function Parent(age) {
  this.age = age;
}
Parent.prototype.sayAge = function () {
  console.log(this.age);
};
function Child(age) {}
Child.prototype = new Parent(18);
const child = new Child();
console.log(child.age); // 18
child.sayAge(); // 18

以上代码中,Child 的原型指向了 Parent 的实例,并且 Child 的实例可以访问到 Parent 中的方法和属性。

3. 组合继承

组合继承是上述两种继承方式的结合。其基本思想是通过构造函数继承实现属性的继承,通过原型链继承实现方法的继承。

function Parent(age) {
  this.age = age;
}
Parent.prototype.sayAge = function () {
  console.log(this.age);
};
function Child(age) {
  Parent.call(this, age);
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
const child = new Child(18);
console.log(child.age); // 18
child.sayAge(); // 18

以上代码中,Child 函数的构造函数中调用了 Parent 的构造函数并传入参数,实现了属性的继承。Child 的原型对象指向了 Parent 的原型对象,并且将 constructor 指向了 Child 函数,实现了方法的继承。

结语

JavaScript 原型链是一种非常重要的特性。理解原型链能够帮助我们更好地理解 JavaScript 的对象模型和继承机制。掌握 JavaScript 原型链的实现方式以及查找顺序可以帮助我们更好地回答面试题。在实际项目中,可以根据练习的需求选择不同的继承方式以实现需求。

深入解析JavaScript原型链面试题

2023-05-21
java笔试面试题整理第八波,java程序员面试笔试真题与解

2022-11-21
java学习笔记(java初学笔记)

2022-11-14
javascript简要笔记,JavaScript读书笔记

2022-11-17
golang笔试,go的面试题

2022-11-27
java面试札记,java面试笔试题大汇总

2022-11-23
javascript入门笔记1的简单介绍

2022-11-18
python基础学习整理笔记,Python课堂笔记

2022-11-21
java笔试题分类总结,java面试题及答案整理

2022-11-16
重学java笔记,java笔记总结

2022-11-23
java基础知识学习笔记一,Java基础笔记

2022-11-21
jsp程序开发学习笔记2,jsp程序设计题库

本文目录一览: 1、《JSP&Servlet学习笔记》pdf下载在线阅读,求百度网盘云资源 2、林信良编著jsp&servlet学习笔记第2版课后答案吗 3、jsp有没有快速掌握的办法呀? 4、要学J

2023-12-08
javascript一句话笔记,javascript基本语句

2022-11-16
python课堂整理32(python笔记全)

2022-11-12
深入理解java并发原理,深入理解java并发原理

2022-12-01
web原生js面试,web开发面试

本文目录一览: 1、有哪些经典的 Web 前端或者 JavaScript 面试笔试题 2、js基础面试题1-10道 3、面试Web前端需要注意什么?会面试哪些问题? 4、Web前端岗位面试题有哪些 有

2023-12-08
每日java学习笔记(java高手笔记)

2022-11-15
腾讯技术部php笔试题(腾讯技术笔试题目)

2022-11-12
java高级笔试面试题(java高级面试题目)

2022-11-12
java方法整理笔记(java总结)

2022-11-08