JavaScript原型与原型链深入探究使用方法

JavaScript原型与原型链深入探究使用方法

原型

JavaScript中每个函数都有一个prototype属性,它指向一个对象。这个对象就是所谓的“原型对象”或“原型”。我们可以在原型对象上添加方法和属性,这些方法和属性可以被构造函数创建的实例所共享。在原型对象上定义的方法和属性,可以被该构造函数所创建的所有实例共享使用。这样,我们就可以省略实例中相同的方法和属性了。

我们可以使用Object.getPrototypeOf()方法获取指定对象的原型对象,或者使用对象的__proto__属性获取其原型对象。

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.sayHello = function() {
  console.log("Hello, I'm " + this.name + " and I'm " + this.age + " years old.");
};

var p1 = new Person("Alice", 23);
var p2 = new Person("Bob", 24);

p1.sayHello(); // Hello, I'm Alice and I'm 23 years old.
p2.sayHello(); // Hello, I'm Bob and I'm 24 years old.

console.log(Object.getPrototypeOf(p1) === Person.prototype); // true
console.log(p1.__proto__ === Person.prototype); // true

原型链

JavaScript中除了Object对象没有原型,其他所有对象都有原型。当我们访问对象的一个属性时,JavaScript引擎会首先在该对象本身查找该属性,如果找到则直接返回该属性的值;如果没有找到,则继续在该对象的原型对象上查找该属性。如果仍然没有找到,则继续在原型对象的原型对象上查找,直到找到该属性或到达Object为止。

这种由多个对象构成的链式结构就是原型链。我们可以使用Object.create()方法来创建一个指定对象的新对象,并把新对象的原型对象指定为该指定对象,从而形成一个原型链。

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.sayHello = function() {
  console.log("Hello, I'm " + this.name + " and I'm " + this.age + " years old.");
};

function Student(name, age, grade) {
  Person.call(this, name, age);
  this.grade = grade;
}

Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
Student.prototype.sayGrade = function() {
  console.log(this.name + "'s grade is " + this.grade + ".");
};

var s1 = new Student("Alice", 23, "A");
var s2 = new Student("Bob", 24, "B");

s1.sayHello(); // Hello, I'm Alice and I'm 23 years old.
s1.sayGrade(); // Alice's grade is A.
s2.sayHello(); // Hello, I'm Bob and I'm 24 years old.
s2.sayGrade(); // Bob's grade is B.

console.log(Object.getPrototypeOf(s1) === Student.prototype); // true
console.log(Object.getPrototypeOf(Student.prototype) === Person.prototype); // true
console.log(Object.getPrototypeOf(Person.prototype) === Object.prototype); // true
console.log(Object.getPrototypeOf(Object.prototype) === null); // true

在上面的示例中,使用Object.create()方法创建了一个新对象,并把原型对象指定为Person.prototype,从而形成了一个原型链。由于我们重写了Student.prototype对象,导致其原型对象不再指向Object.prototype,所以要手动给Student.prototype重新设置constructor属性。在该原型链中,Student的实例Student.prototype的原型对象是Person.prototypePerson的实例的原型对象是Object.prototype,最高层原型对象是null。为了提高代码的可读性,我们可以使用ES5中新增的Object.setPrototypeOf()方法来设置对象的原型对象。

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.sayHello = function() {
  console.log("Hello, I'm " + this.name + " and I'm " + this.age + " years old.");
};

function Student(name, age, grade) {
  Person.call(this, name, age);
  this.grade = grade;
}

Object.setPrototypeOf(Student.prototype, Person.prototype);
Student.prototype.sayGrade = function() {
  console.log(this.name + "'s grade is " + this.grade + ".");
};

var s1 = new Student("Alice", 23, "A");
var s2 = new Student("Bob", 24, "B");

s1.sayHello(); // Hello, I'm Alice and I'm 23 years old.
s1.sayGrade(); // Alice's grade is A.
s2.sayHello(); // Hello, I'm Bob and I'm 24 years old.
s2.sayGrade(); // Bob's grade is B.

console.log(Object.getPrototypeOf(s1) === Student.prototype); // true
console.log(Object.getPrototypeOf(Student.prototype) === Person.prototype); // true
console.log(Object.getPrototypeOf(Person.prototype) === Object.prototype); // true
console.log(Object.getPrototypeOf(Object.prototype) === null); // true

示例说明

示例一

在以下示例中,我们定义了一个Animal的构造函数,该构造函数拥有一个eat方法的原型。我们接着从Animal继承一个Dog构造函数,并通过原型链给Dog添加一个bark方法。最后,使用Dog构造函数创建了一个d对象。我们可以发现,d可以调用eatbark两个方法。

function Animal(name) {
    this.name = name;
}

Animal.prototype.eat = function() {
    console.log(this.name + " is eating.");
};

function Dog(name) {
    this.name = name;
}

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.bark = function() {
    console.log(this.name + " is barking.");
};

var d = new Dog("Gunner");
d.eat();
d.bark();

示例二

在以下示例中,我们定义了一个Shape的构造函数,该构造函数拥有一个getType方法的原型。我们接着从Shape继承一个Rectangle构造函数,并重写了该构造函数的getType方法来返回特定的type属性。最后,使用Rectangle构造函数创建了一个r对象。我们可以发现,rgetType方法返回了rectangle

function Shape() { }

Shape.prototype.getType = function() {
    return "shape";
}

function Rectangle() { }

Rectangle.prototype = Object.create(Shape.prototype);

Rectangle.prototype.constructor = Rectangle;

Rectangle.prototype.getType = function() {
    return "rectangle";
}

var r = new Rectangle();
console.log(r.getType());

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript原型与原型链深入探究使用方法 - Python技术站

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

相关文章

  • 解析js中获得父窗口链接getParent方法以及各种打开窗口的方法

    解析js中获得父窗口链接getParent方法以及各种打开窗口的方法 在Web开发中,我们经常需要在网页中打开新的窗口,并且还会经常需要获取当前窗口的父窗口。本文将介绍如何使用JavaScript来获取父窗口的链接,并且介绍常用的打开窗口的方法。 获取父窗口链接 可以使用 JavaScript 中的 parent 对象来获取当前窗口的父窗口对象。父窗口对象包…

    JavaScript 2023年6月11日
    00
  • 详解JS中统计函数执行次数与执行时间

    首先我们需要明确一下,统计函数执行次数和执行时间是一个常见的需求,它有助于我们优化代码,找到潜在的性能瓶颈,提高应用程序的性能。那么,在JS中如何统计函数执行次数和执行时间呢? 统计函数执行次数 我们可以定义一个计数器来记录函数执行的次数。例如,下面的代码演示了如何统计函数foo的执行次数: let count = 0; function foo() { /…

    JavaScript 2023年5月27日
    00
  • JavaScript中setUTCFullYear()方法的使用简介

    JavaScript中setUTCFullYear()方法的使用简介 什么是setUTCFullYear()方法? setUTCFullYear()方法是JavaScript中Date对象的方法之一。用于设置Date对象的年份,根据协调世界时(UTC)进行设置。 该方法的语法 setUTCFullYear(year, month, day) 参数: year…

    JavaScript 2023年6月10日
    00
  • javascript流程控制语句集合

    JavaScript 流程控制语句集合 在 JavaScript 中,流程控制语句可以让我们根据不同条件执行不同的操作,这对于编写复杂的程序非常重要。JavaScript 中的流程控制语句集合主要包括以下三个部分: 条件语句 循环语句 控制语句 条件语句 条件语句可以让我们根据不同的条件执行不同的程序代码。在 JavaScript 中,条件语句主要包括以下两…

    JavaScript 2023年5月27日
    00
  • jquery实现浮动在网页右下角的彩票开奖公告窗口代码

    下面我将详细讲解“jquery实现浮动在网页右下角的彩票开奖公告窗口代码”的攻略。 基本思路 我们的目标是实现一个浮动在网页右下角的彩票开奖公告窗口。具体实现思路如下: 在页面底部右下角添加一个固定宽度和高度的 div 元素,设置其 position 属性为 fixed,bottom 和 right 属性为 0,这样就可以让该元素始终浮动在页面的右下角。 在…

    JavaScript 2023年6月11日
    00
  • javascript三种代码注释方法

    JavaScript中有三种注释方法:单行注释、多行注释和文档注释。 1. 单行注释 单行注释用于注释一行代码,使用双斜杠(//)开头。 示例: // 这是一行单行注释 console.log("Hello World!"); 输出结果: Hello World! 2. 多行注释 多行注释用于注释多行代码,使用斜杠星号(/*)作为开始标记…

    JavaScript 2023年5月18日
    00
  • javascript中eval解析JSON字符串

    JavaScript中的eval()函数可以将JSON格式的字符串解析为可操作的JavaScript对象,从而方便地在应用程序中使用。下面就是详细的攻略: 什么是JSON字符串? JSON(JavaScript对象表示法)是一种轻量级的数据交换格式,用于存储和交换数据。它基于JavaScript语法,但具有更宽泛的应用范围,因为许多编程语言都支持它。 JSO…

    JavaScript 2023年5月27日
    00
  • JavaScript的事件监听你了解吗

    当我们在JavaScript中进行开发时,常常需要监听某些事件来采取相应的行动。事件指用户正在进行的操作,如鼠标移动、点击按钮等交互行为。JavaScript提供了一种机制来监听事件并执行相关的操作,这就是JavaScript的事件监听机制。 什么是事件监听机制? 在JavaScript中,事件监听机制是指通过给元素(如按钮、输入框等)添加事件处理器,从而在…

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