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日

相关文章

  • 关于导入excel时js转换时间的正确方式

    针对“关于导入Excel时JS转换时间的正确方式”的问题,我准备提供以下攻略: 标准日期格式 在Excel中,日期一般使用“yyyy-mm-dd”或“yyyy/mm/dd”的格式表示,如果以文本形式存储的话,在JS中转换日期时会出现错误。因此,在将Excel表格中的日期数据导入时,需要对日期进行预处理,将其按照标准的日期格式进行存储。这里推荐使用xlsx或e…

    JavaScript 2023年5月27日
    00
  • 跨站攻击之实现Http会话劫持的手法

    跨站攻击(Cross-Site Attack)又称为XSS攻击,是指攻击者在网页中插入恶意脚本,使受害者在访问网页时,网页中的恶意脚本被执行从而攻击受害者。跨站攻击有很多种形式,其中之一就是Http会话劫持,下面我们来看看这种手法的攻略。 什么是Http会话劫持 Http会话劫持是指攻击者在网站上注入一段代码,通过劫持用户已经建立的会话从而获取用户的权限、获…

    JavaScript 2023年6月11日
    00
  • 微信小程序项目实践之九宫格实现及item跳转功能

    以下是《微信小程序项目实践之九宫格实现及item跳转功能》的完整攻略。 1. 确定页面结构 首先,我们需要确定页面的基本结构,包括 view、scroll-view、block 等组件。页面结构如下: <!– page.wxml –> <scroll-view class="grid-container"> &…

    JavaScript 2023年6月11日
    00
  • 教你javascript如何获取指针的位置

    教你javascript如何获取指针的位置 什么是指针? 在计算机中,指针是一个变量,存储了一个内存地址,该地址指向一个数据单元。指针可以被用来直接访问和修改内存中的数据,因此它在程序中非常有用。 在JavaScript中,由于其具有自动内存管理机制,因此没有指针类型。但是,在某些情况下,我们需要获取鼠标指针在页面中的位置。 获取鼠标指针位置 在JavaSc…

    JavaScript 2023年6月11日
    00
  • JS实现手写 forEach算法示例

    当我们需要在JavaScript中对数组中的每个元素进行操作时,可以使用forEach方法。但是,如果我们想要深入了解forEach方法的实现过程,那么我们可以使用手写forEach算法来了解它的原理。 实现步骤 首先,我们需要明确手写forEach算法的实现步骤: (1)接收一个数组和一个回调函数作为参数; (2)依次遍历数组中的每个元素; (3)对每个元…

    JavaScript 2023年5月28日
    00
  • vue之keepAlive使用案例详解

    Vue之keepAlive使用案例详解 概述 Vue中的keep-alive是一个抽象组件,用于缓存动态组件或router-view之间的状态。当一个keep-alive包裹的组件在它们之间切换时,组件不会被销毁和重新创建,它只是被缓存起来,直到下次被需要时再进行渲染。 基本使用 在需要进行缓存的组件外部添加<keep-alive>标签,并在该标…

    JavaScript 2023年6月11日
    00
  • Ajax请求二进制流进行处理(ajax异步下载文件)的简单方法

    对于Ajax请求二进制流进行处理的攻略可以分为以下几个步骤: 1. 发送二进制流文件 首先,在服务端需要将文件转换为二进制流格式并以这种格式进行传输。可以使用以下PHP代码示例: $file = ‘example.xlsx’; header(‘Content-Description: File Transfer’); header(‘Content-Type…

    JavaScript 2023年6月11日
    00
  • JS将指定的某个字符全部转换为其他字符实例代码

    下面是完整的攻略,包含了示例代码和说明: 思路: 我们可以通过JS的字符串处理方法,将指定字符串中的某个字符全部替换为其他字符。具体而言,我们可以使用字符串的replace()函数实现替换功能,该函数接受两个参数,分别表示要替换的字符和用于替换的字符。 下面是基本的replace()函数语法: str.replace(searchValue, replace…

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