📕 重学JavaScript:你理解原型链吗?

简介: 在 JavaScript 中,我们整个编码过程都离不开”对象“,这个看起来简单的且基础的东西,却蕴含着着很多的知识点。也是我们理解原型链非常重要的一个辅助工具🔧。

📕 重学JavaScript:你理解原型链吗?

嗨,大家好!这里是道长王jj~ 🎩🧙‍♂️

你知道我们常说的JavaScript中的”对象“是什么吗?

我们在编码过程中经常使用存储很多信息📦。比如说,你可以用一个对象来描述一个人,他有什么名字,多大年纪,会做什么事情等等。

在 JavaScript 中,我们整个编码过程都离不开”对象“,这个看起来简单的且基础的东西,却蕴含着着很多的知识点。也是我们理解原型链非常重要的一个辅助工具🔧。

❓ 原型对象和构造函数有何关系?

我们先来举个例子:

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 alice = new Person("Alice", 18);

alice.sayHello(); // Hello, I'm Alice, and I'm 18 years old.

var bob = new Person("Bob", 20);

bob.sayHello(); // Hello, I'm Bob, and I'm 20 years old.

// alice.sayHello === bob.sayHello

首先,我们定义了一个构造函数👷‍♂️,叫做 Person。构造函数就是一个特殊的函数,它可以用来创建对象。这个构造函数接受两个参数:name 和 age。当我们用 new 关键字来调用这个构造函数时,它会给新创建的对象设置两个属性:name 和 age。这两个属性的值就是我们传入的参数。

然后,我们在 Person 的原型对象👥上定义了一个方法,叫做 sayHello。原型对象就是一个包含了很多属性和方法的东西,它可以被所有由 Person 构造函数创建的对象所共享。这个方法会打印出对象的名字和年龄,并且说一句你好。我们用 this 关键字来指代当前调用这个方法的对象。

所以,我们首先就得到了这样一组关系

graph LR;
    A[Person构造函数] --prototype--> B[原型对象];
    B--constructor--> A;

接着,我们用 new 关键字来实例化👶 Person 构造函数,传入两个参数,创建了两个新的对象,分别叫做 Alice 和 bob。new 关键字会让 JavaScript 帮我们做以下几件事情:

  • 创建一个空的对象;
  • 把这个空对象的原型对象设置为 Person 的原型对象;
  • 把这个空对象作为 this 的值传给 Person 构造函数,并执行它;
  • 返回这个空对象(如果 Person 构造函数没有返回其他对象的话)。

所以,Alice 和 bob 这两个对象就有了 name 和 age 这两个属性,也有了 sayHello 这个方法。我们可以调用他们各自的 sayHello 方法,让它打印出自己的名字和年龄。注意,他们调用的是同一个方法。

我们就可以完善这一组关系:

graph LR;
    A[Person构造函数] --prototype--> B[原型对象];
    B--constructor--> A;
    A--new-->C[实例对象];
    C--_proto_-->B

这组关系说明,每个函数都有一个特殊的属性,叫做 prototype。这个属性指向了一个对象,叫做函数的原型对象👥。这个原型对象里面有一些属性和方法,它们可以被所有由这个函数创建的对象所共享。

当你用 new 关键字来调用一个函数时,这个函数就变成了一个构造函数👷‍♂️。它会返回一个全新的对象,叫做实例对象👶。这个实例对象有一个隐藏的属性,叫做 _proto_。这个属性指向了构造函数的原型对象。

❓ 什么又是原型链呢?

原型链是 JavaScript 中的一个非常重要的概念,它可以被形象地理解成由一些原型对象连起来的一条链子,用于表示对象之间的继承关系👩‍👧。在 JavaScript 中,每个对象都有一个隐藏的属性,叫做 _proto_。这个属性指向了这个对象的原型对象👥。如果我们在这个对象上找一个属性或方法,而这个对象本身没有这个属性或方法,那么就会沿着原型链向上找,直到找到这个属性或方法为止😊。

让我们来看一个简单的例子吧😉:

classDiagram
    Object <|-- Person
    Person <|-- p1
    Object : +__proto__
    Object : +constructor
    Person : +__proto__
    Person : +constructor
    p1 : +__proto__
    p1 : +constructor
    Object ..> Object: __proto__
    Person ..> Object: __proto__
    p1 ..> Person: __proto__

在这个例子中,Object 是所有对象的老祖宗👴,Person 是 Object 的孩子👶,p1 是 Person 的孩子👶。当我们创建一个 Person 实例时,它会继承 Object 的所有属性和方法。如果我们在 Person 实例上找一个属性或方法,而这个实例本身没有这个属性或方法,那么就会沿着原型链向上找,直到找到这个属性或方法为止。原型链最后会的原型对象是Object,Object最终会指向null 即原型链的终点。

💌 番外:如何判断原型上有没有这个属性

  • 对象的 hasOwnProperty() 来检查对象自身中是否含有该属性
  • 使用 in 检查对象中是否含有某个属性时,如果对象中没有但是原型链中有,也会返回 true
// 定义一个对象
var obj = {
   
  name: "Bing",
  age: 10
};

// 定义一个构造函数
function Person(name, age) {
   
  this.name = name;
  this.age = age;
}

// 给Person的原型添加一个属性
Person.prototype.gender = "male";

// 创建一个Person的实例
var p = new Person("Tom", 20);

// 使用hasOwnProperty()来检查对象自身中是否含有该属性
console.log(obj.hasOwnProperty("name")); // true
console.log(obj.hasOwnProperty("gender")); // false
console.log(p.hasOwnProperty("name")); // true
console.log(p.hasOwnProperty("gender")); // false

// 使用in检查对象中是否含有某个属性时,如果对象中没有但是原型链中有,也会返回true
console.log("name" in obj); // true
console.log("gender" in obj); // false
console.log("name" in p); // true
console.log("gender" in p); // true

🎉 你觉得怎么样?这篇文章可以给你带来帮助吗?如果你有任何疑问或者想进一步讨论相关话题,请随时发表评论分享您的想法,让其他人从中受益。🚀✨

目录
相关文章
|
19天前
|
JavaScript 前端开发
谈谈对 JavaScript 中的原型链的理解。
JavaScript中的原型链是实现继承和共享属性的关键机制,它通过对象的`prototype`属性连接原型对象。当访问对象属性时,若对象本身没有该属性,则会查找原型链。此机制减少内存占用,实现代码复用。例如,实例对象可继承原型对象的方法。原型链也用于继承,子类通过原型链获取父类属性和方法。然而,原型属性共享可能导致数据冲突,且查找过程可能影响性能。理解原型链对JavaScript面向对象编程至关重要。如有更多问题,欢迎继续探讨😊
16 3
|
19天前
|
JavaScript 前端开发
深入理解JavaScript中的原型链
本文将深入探讨JavaScript中的原型链机制,从根本上理解它的工作原理以及在开发中的应用。我们将介绍原型链的概念、如何创建和使用原型、原型链的继承机制以及一些常见的原型链相关问题。通过对原型链的详细解析,读者将能够更好地理解JavaScript中的继承、原型对象和原型链之间的关系,提高代码的质量和可维护性。
|
19天前
|
存储 前端开发 JavaScript
揭秘原型链:探索 JavaScript 面向对象编程的核心(下)
揭秘原型链:探索 JavaScript 面向对象编程的核心(下)
揭秘原型链:探索 JavaScript 面向对象编程的核心(下)
|
19天前
|
前端开发 JavaScript 开发者
揭秘原型链:探索 JavaScript 面向对象编程的核心(上)
揭秘原型链:探索 JavaScript 面向对象编程的核心(上)
揭秘原型链:探索 JavaScript 面向对象编程的核心(上)
|
19天前
|
存储 JavaScript 前端开发
原型链:揭开JavaScript背后的神秘面纱
原型链:揭开JavaScript背后的神秘面纱
|
19天前
|
JavaScript 前端开发 安全
JavaScript原型链的使用
【4月更文挑战第22天】JavaScript中的原型链是理解继承的关键,它允许对象复用属性和方法,减少代码冗余。示例展示如何通过原型链实现继承、扩展内置对象、构造函数与原型链的关系以及查找机制。应注意避免修改`Object.prototype`,使用安全方式设置原型链,并谨慎处理构造函数和副作用。
|
19天前
|
JavaScript 前端开发
JavaScript原型,原型链
JavaScript原型,原型链
|
13天前
|
JavaScript 前端开发
前端 JS 经典:原型和原型链
前端 JS 经典:原型和原型链
20 0
|
17天前
|
前端开发 JavaScript
前端 js 经典:原型对象和原型链
前端 js 经典:原型对象和原型链
25 1
|
18天前
|
JavaScript 前端开发
JavaScript 原型链继承:掌握面向对象的基础
JavaScript 原型链继承:掌握面向对象的基础