一文彻底理解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两个对象的属性和方法,并且还添加了自己的属性和方法。

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

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

相关文章

  • linux查看服务器开放的端口和启用的端口多种方式

    需要查看Linux服务器上已开放和启用的端口,可以使用以下多种方式: 方式 1:使用 netstat 命令查看端口状态 打开终端,输入以下命令来查看服务器开放的所有端口的状态: netstat -an 输出结果中,所有的端口都会显示其状态(Listening、Established、Closed、等等)。 如果想要查看特定端口的状态,可以使用: netsta…

    other 2023年6月27日
    00
  • Win7月度更新补丁KB4019264(KB4015552)下载地址(附更新、已知内容汇总)

    Win7月度更新补丁KB4019264(KB4015552)下载地址(附更新、已知内容汇总)攻略 1. 简介 Win7月度更新补丁KB4019264(KB4015552)是针对Windows 7操作系统的重要安全更新补丁。本攻略将详细介绍如何下载该补丁以及提供已知内容的汇总。 2. 下载地址 你可以通过以下步骤下载Win7月度更新补丁KB4019264(KB…

    other 2023年8月4日
    00
  • @Autowired注解在抽象类中失效的原因及解决

    自动装配(autowiring)是Spring框架提供的一种便捷的方式,可以自动将相互依赖的组件(bean)注入到Java类中。@Autowired注解可以实现自动注入,但是在抽象类中有时会失效。下面是@Autowired注解在抽象类中失效的原因及解决方案的完整攻略。 原因 @Autowire注解功能实现的原理是Spring容器在启动时,扫描所有使用@Com…

    other 2023年6月26日
    00
  • C#实现多选项卡的浏览器控件

    C#实现多选项卡的浏览器控件的攻略可以分为以下步骤: 设计控件的外观与行为 首先,我们需要考虑该控件的外观应该怎样设计。通常情况下,一个浏览器控件需要包含以下元素: 顶部工具栏:提供网址输入框、前进/后退/刷新按钮等功能; 多个选项卡:每个选项卡显示一个网页; 主要区域:显示当前选项卡打开的网页内容。 因此,我们可以设计一个包含以上三个元素的用户控件,并在控…

    other 2023年6月26日
    00
  • python算法题 链表反转详解

    Python算法题-链表反转详解 1. 题目描述 给定一个单链表,将其翻转。例如: 输入: 1 -> 2 -> 3 -> 4 -> None 输出: 4 -> 3 -> 2 -> 1 -> None 2. 解法分析 链表是一种动态数据结构,它不要求内存必须按照线性顺序连续分布,相对于数组来说,它更加灵活。 链表…

    other 2023年6月27日
    00
  • 微信小程序websocket聊天室的实现示例代码

    关于“微信小程序websocket聊天室的实现示例代码”,下面是详细的攻略。 1.什么是WebSocket WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议与HTTP协议属于同一级别,所以在建立连接时使用的是HTTP请求,只不过请求头的一些字段不同。与 HTTP 协议不同的是,WebSocket在…

    other 2023年6月27日
    00
  • javascript自动点击

    JavaScript自动点击 在现代 Web 应用中,自动化测试已经越来越受到重视。为了模拟用户操作,在测试过程中可能需要用到自动点击功能。 JavaScript 提供了一些开发工具,可以用它们来模拟用户事件操作。下面将介绍如何使用 JavaScript 来实现自动点击。 添加事件监听 首先,需要选择需要自动点击的 DOM 元素。为了在这个 DOM 元素上执…

    其他 2023年3月28日
    00
  • uniapp基础知识点掌握以及面试题整理

    uniapp基础知识点掌握以及面试题整理 1. uniapp基础知识点掌握 1.1 什么是uniapp? uniapp是一个使用Vue.js开发跨平台应用的前端框架,可以一次编写,多端发布,支持H5、小程序、APP等多种平台。uniapp开发与Vue.js开发类似,采用MVVM模式,通过数据绑定实现视图的响应式渲染。 1.2 uniapp的项目结构和文件组织…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部