对js原型和原型链的理解

本文介绍了JavaScript中的原型和原型链。每个函数都有一个`prototype`属性,它指向原型对象,用于实例共享属性和方法。实例对象有`__proto__`属性指向构造函数的原型。原型对象也有`constructor`属性指向构造函数。通过`__proto__`和`prototype`,建立了实例、原型和构造函数之间的关系。原型链使得实例可以访问原型和原型的原型上的属性和方法,直至到达Object.prototype,其`__proto__`指向null,构成原型链的终点。
摘要由CSDN通过智能技术生成
       学习到 JavaScript 原型这个地方的时候,最开始是比较懵的状态,今天早上起来看了下红宝书中对于原型的解释,慢慢的也就有了些了解,但是解释的比较官方。接下来,我会把自己的理解分享下来,尽量用通俗易懂的话来描述。如果有什么不对的地方,希望大家指正。

1、原型

1.1 prototype

       JavaScript 中,当创建一个函数的时候,这个函数就会自动创建一个 prototype 属性,该属性指向的就是原型对象。既然这个属性指向了原型对象,那么他能不能使用原型中的属性和方法呢?

先来看创建的实例访问构造函数中的属性和方法

// 构造函数
function Me() {
   
  this.uName = "shuang";
  this.sayName = function () {
   
    console.log(this.uName);
  };
}

let m1 = new Me(); // 创建实例
console.log(m1.uName) // shuang;
m1.sayName(); // shuang

下面我尝试用原型来创建新的属性和方法

// 构造函数
function Me() {
   
  this.uName = "shuang";
  this.sayName = function () {
   
    console.log(this.uName);
  };
}

let m1 = new Me(); // 创建实例
console.log(m1.uName) // shuang;
m1.sayName(); // shuang

Me.prototype.sex = "男";
Me.prototype.saySex = function () {
   
  console.log(this.sex);
}
console.log(m1.sex); // 男
m1.saySex(); // 男

       通过上面的案例可以很清楚的认识到,可以通过 prototype 指向的原型对象中添加新的属性和方法,并且可以通过实例进行访问。

       这里总结出来,每一个函数被创建的时候,会创建一个 prototype 属性,这个属性是一个对象,这个对象就是通过调用构造函数创建的对象的原型。在原型对象上面定义的属性和方法可以被实例共享。不仅可以在构造函数中创建属性和方法,也可以将属性和方法直接赋值给他们的原型。

用一个图来描述构造函数与原型的关系
在这里插入图片描述

1.2 __proto__(前后各是两个下划线)

       上面了解到了构造函数与原型对象中通过 prototype 这个属性进行联系。我发现,上述代码创建的实例中,也可以访问到通过原型创建的属性和方法,那么考虑,实例与原型之间是否有某种联系呢?

这里稍微做一个小科普,在红宝书中有这么一段话:
每次调用构造函数创建的一个新实例,这个实例的内部有一个 [[Prototype]] 指针就会被赋值为构造函数的原型对象,因为 JavaScript 脚本中没有访问这个 [[Prototype]] 特性的标准方式,但是 Firefox、Safari 和 Chrome 会在每个对象上暴露 __proto__属性,通过这个属性可以访问对象的原型。
如果打印一下构造函数的 prototype 属性就会在浏览器中出现下面代码:

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

// 获取 构造函数 的 prototype 属性
console.log(Person.prototype);

在这里插入图片描述

这里在允许我做一个科普,上面的代码结果是我在 chrome 90版本之前执行的结果,现在最新的 chrome 浏览器将 __proto__ 这个属性变成了 [[Prototype]],正是红宝书提到的。
但是不用担心,因为在编写代码的时候,依旧没有 [[Prototype]] 这么一个属性,所以依旧可以使用 __proto__ 这个属性来访问原型,只是说今后如果在 chrome 浏览器中遇到了 [[Prototype]] 这个属性,要知道他其实就是 __proto__属性。
光说不够直白,下面我用最新版的 chrome 浏览器打印一下构造函数的 prototype 属性:

// 构造函数
function Me() {
   
  this.uName = "shuang";
  this.sayName = function () {
   
    console.log(this.uName);
  };
}

// 获取 构造函数 的 prototype 属性
console.log(Me
  • 15
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凉爽爽爽爽爽爽爽爽爽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值