一文彻底理解JavaScript原型与原型链

下面就是详细讲解“一文彻底理解JavaScript原型与原型链”的完整攻略:

一、JavaScript中的原型

JavaScript中的原型(prototype)是指每个函数都有一个prototype属性,它是一个指向对象的指针。prototype指针所指向的对象被称为原型对象。

1.1 构造函数与原型

当一个函数用来作为构造函数时,它所创建的对象都有一个隐式的原型指向它的prototype属性所指向的原型对象。例如:

function Person(name, age) {
    this.name = name;
    this.age = age;
}
var person1 = new Person('小明', 18);

上面的代码中,Person函数是一个构造函数,用来创建person1对象。因为Person函数有一个prototype属性,所以person1对象隐式地有了一个指向Person.prototype指向的原型对象的__proto__属性。我们可以通过以下代码验证:

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

1.2 原型对象的作用

原型对象的作用是为实例对象添加属性或方法。每当我们创建一个新对象时,这个对象都会自动包含一个指向原型对象的__proto__属性。这个属性包含了原型对象中所有可访问的方法和属性。

例如,我们可以在Person构造函数的原型对象中添加一个函数greet,这个函数可以在person1对象中使用,代码如下:

Person.prototype.greet = function() {
    console.log('Hello, I am ' + this.name + ', I am ' + this.age + ' years old.');
}
person1.greet(); // Hello, I am 小明, I am 18 years old.

1.3 特殊的__proto__属性

原型对象有一个特殊的__proto__属性,它指向原型链中的上一级原型对象。例如:

function Animal() {}
function Dog() {}
Dog.prototype = new Animal();
var dog1 = new Dog();
console.log(dog1.__proto__ === Dog.prototype); // true
console.log(Dog.prototype.__proto__ === Animal.prototype); // true

我们可以看到,dog1的__proto__属性指向Dog.prototype,而Dog.prototype的__proto__属性指向Animal.prototype。这就形成了原型链。

二、JavaScript中的原型链

原型链是由一个个原型对象组成的链表,形成一个父子关系的层次结构。在JavaScript中,每个对象都有一个__proto__属性,通过这个属性可以找到它的原型对象,原型对象也有一个__proto__属性,指向它的父级原型对象,通过这样的方式就建立了一个由原型对象组成的层次结构,被称为原型链。

2.1 原型链的访问规则

当我们访问一个对象的一个属性时,JavaScript引擎会首先查找这个对象本身的属性,如果找不到,就会去它的__proto__属性指向的原型对象中查找该属性。如果在这个原型对象中也找不到,JavaScript就会继续查找原型对象的__proto__属性指向的父级原型对象,一直查找到最顶层的Object类型为止。

例如,我们可以在Animal构造函数的原型对象中添加一个greet函数,然后在Dog构造函数中添加一个run函数。代码如下:

function Animal() {}
Animal.prototype.greet = function() {
    console.log('I am an animal.');
}
function Dog() {}
Dog.prototype.run = function() {
    console.log('I can run fast!');
}
Dog.prototype.__proto__ = Animal.prototype;
var dog1 = new Dog();
dog1.greet(); // I am an animal.
dog1.run(); // I can run fast!

我们可以看到,dog1对象本身并没有greet和run方法,但是它可以通过原型链访问到Animal和Dog的原型对象,从而调用它们的方法。

2.2 instanceof运算符的实现原理

instanceof运算符可以判断一个对象是否是某个构造函数的实例。这个运算符的实现原理是通过逐级查找对象的__proto__指向的原型对象,直到找到构造函数的原型对象为止。

例如:

console.log(dog1 instanceof Dog); // true
console.log(dog1 instanceof Animal); // true
console.log(dog1 instanceof Object); // true

我们可以看到,因为dog1的原型链中有Dog.prototype、Animal.prototype和Object.prototype,所以它既是Dog的实例,也是Animal和Object的实例。

三、示例说明

3.1 实现原型继承

原型继承是一种常用的面向对象编程技术。它通过在构造函数的原型对象上添加新的属性和方法来实现继承。

例如,我们可以通过以下代码实现一个Person对象继承自Animal对象:

function Animal(name) {
    this.name = name;
}
Animal.prototype.greet = function() {
    console.log('I am an animal.');
}
function Person(name, age) {
    Animal.call(this, name);
    this.age = age;
}
Person.prototype = Object.create(Animal.prototype);
Person.prototype.constructor = Person;
Person.prototype.introduce = function() {
    console.log('Hello, I am ' + this.name + ', I am ' + this.age + ' years old.');
}
var person1 = new Person('小明', 18);
person1.greet(); // I am an animal.
person1.introduce(); // Hello, I am 小明, I am 18 years old.

我们可以看到,Person对象继承了Animal对象的属性和方法,并且还添加了自己的属性和方法。

3.2 实现多层原型链继承

原型链继承可以用来实现多层继承,它通过在父对象的原型对象上添加新的属性和方法,然后在子对象的原型对象上添加一个指向父对象原型对象的__proto__属性。

例如,我们可以通过以下代码实现一个Animal对象,再通过Dog对象继承Animal对象,在通过Golden对象继承Dog对象:

function Animal() {}
Animal.prototype.greet = function() {
    console.log('I am an animal.');
}
function Dog() {}
Dog.prototype = new Animal();
Dog.prototype.bark = function() {
    console.log('Woof!');
}
function Golden() {}
Golden.prototype = new Dog();
Golden.prototype.play = function() {
    console.log('I love playing fetch!');
}
var golden1 = new Golden();
golden1.greet(); // I am an animal.
golden1.bark(); // Woof!
golden1.play(); // I love playing fetch!

我们可以看到,Golden对象通过多层原型链继承了Animal、Dog两个对象的属性和方法,并且还添加了自己的属性和方法。

阅读剩余 70%

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:一文彻底理解JavaScript原型与原型链 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • c语言求两个字符串的交集

    要求求两个字符串的交集,可按以下步骤进行: 步骤一:获取输入的两个字符串 在程序中先定义两个字符串数组,用来保存输入的两个字符串。可使用scanf()函数实现字符串输入。提醒:为避免数组越界等问题,请设定好字符串数组的固定长度,如100。 char str1[100], str2[100]; printf("请输入字符串1:"); sca…

    other 2023年6月20日
    00
  • 剑侠情缘手游装备强化玩法详细介绍

    剑侠情缘手游装备强化玩法详细介绍 强化概述 剑侠情缘手游中,装备强化是提高装备属性的主要途径之一。强化可以提高装备的基础属性,比如攻击力、防御力等,并且还有概率会出现额外属性,比如攻击力加成、暴击等。强化等级越高,装备属性提升越多,但强化失败会降低装备属性。 强化流程 打开游戏,进入角色界面,选择需要强化的装备。 点击装备右下角的强化按钮,进入强化界面。此时…

    other 2023年6月27日
    00
  • php日期格式化方法详解

    PHP日期格式化方法详解 在开发中,我们常常需要对日期进行格式化,比如要将日期转成字符串,或者将字符串转成日期对象。PHP 提供了丰富的日期格式化方法,本文将对常用的格式化方法进行详细讲解。 将日期时间格式化为字符串 使用 PHP 内置的 date 函数可以将日期时间格式化为字符串。该函数的第一个参数为格式化字符串,用于指定输出的格式。 下面是一些常用的格式…

    其他 2023年3月28日
    00
  • iOS16如何自定义Home应用程序 iOS16自定义Home应用程序方法

    iOS16如何自定义Home应用程序 在iOS 14及之前的版本中,我们只能通过在App库中搜索要添加的应用程序并将其放置在主屏幕上,但在iOS 15及之后的版本中,我们可以使用自定义应用库和自定义主屏幕来实现自定义排序和分类应用程序。本文将介绍如何使用iOS 16来自定义Home应用程序。 步骤1. 创建自定义应用程序 您可以在iOS 16的应用程序库中创…

    other 2023年6月25日
    00
  • 使用Python对MySQL数据操作

    使用Python对MySQL数据操作的完整攻略 1. 安装MySQL驱动程序 在开始之前,我们需要安装Python的MySQL驱动程序。可以使用pip命令来安装,运行以下命令: pip install mysql-connector-python 2. 连接到MySQL数据库 在Python中,我们可以使用mysql.connector模块来连接到MySQL…

    other 2023年8月3日
    00
  • go语言学习之包和变量详解

    Go语言学习之包和变量详解 1. 包(Package) 在Go语言中,包是组织代码的基本单位。一个包可以包含多个Go源文件,这些文件可以是函数、变量、常量和类型的集合。通过使用包,我们可以将代码模块化,提高代码的可读性和可维护性。 1.1 包的声明 在每个Go源文件的开头,我们需要声明所属的包。包的声明使用package关键字,后面跟着包的名称。例如,下面是…

    other 2023年7月29日
    00
  • 魔兽世界7.3.5踏风怎么堆属性 wow7.35踏风配装属性优先级攻略

    魔兽世界7.3.5踏风怎么堆属性 wow7.35踏风配装属性优先级攻略 介绍 在魔兽世界中,属性可以影响角色的战斗力。在踏风职业中,最重要的属性为敏捷和暴击。但是,对于不同的职业和不同的装备,属性的优先级可能会有所不同。本文中将详细介绍如何堆属性以及属性的优先级。 如何堆属性 对于踏风职业来说,敏捷和暴击是最重要的属性。因此,装备中应该优先选择具有高敏捷和暴…

    other 2023年6月27日
    00
  • mysql中的虚拟列

    Mysql中的虚拟列 Mysql是一个广泛使用的关系型数据库管理系统,它通过使用列来存储和管理数据。在Mysql中,虚拟列是一种特殊的列,它不存储数据,而是根据其他列计算出虚拟列的值。虚拟列的值不会影响数据库表中已存储的数据。 创建虚拟列 在Mysql中,通过在CREATE TABLE语句中使用AS关键字,就可以创建虚拟列。以下是创建虚拟列的示例: CREA…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部