JavaScript 实例,原型,原型链

前言

如果想真正理解实例,原型,原型链是什么,以及他们的关系我们就必须搞清楚基本的概念性知识。

函数

构造函数部分我们要了解以下几个问题:

  1. 函数是什么?
  2. 构造函数与普通函数有什么区别?
  3. 什么是构造函数?

答:

  1. 函数是对象。
  2. 构造函数与普通函数没有区别,只不过按照惯例,构造函数命名要采取大驼峰写法。
  3. 使用了new操作符调用的函数,就是构造函数。函数本身并没有是不是构造函数的概念,只不过是你调用的方式不同,赋给了他不同的概念。

创建一个构造函数:

function Person(){};

console.log(Person instanceof Object); // true 

let person = new Person(); // Person被作为构造函数调用,并不妨碍Perosn当作普通函数使用
Person(); // 我是当作普通函数被调用

实例

实例部分我们需要了解一个问题:

  1. 那么是什么实例?

答:

  1. 使用new操作符创建的新对象就是实例。

理解:你可以将Person函数当作人的模型,将lucy变量当作具体的一个人。

function Person(name){
	this.name = name;
};
let lucy = new Person('lucy'); // lucy就是实例 
console.log(lucy.name); // lucy

原型

原型部分我们需要了解一下几个问题:

  1. 原型的作用。
  2. 原型在哪里。

答:

  1. 原型是用于存放公共的属性和方法,并且在原型上定义的属性和方法可以被实例共享。
  2. 函数的prototype属性就是原型。

下面让我们具体体验下原型的作用,我们先不使用原型的知识来创建两个实例。

function Person(name) {
	this.name = name;
	this.greet = function() {
		console.log(`Hello, My name is ${this.name}`);
	};
}

lucy = new Person('Lucy');
lucy.greet(); // Hello, My name is Lucy

bob = new Person('Bob');
bob.greet(); // Hello, My name is Bob

那么让我们比较lucy.greet方法与bob.greet方法两者是否相等。

console.log(lucy.greet == bob.greet); // false

结果显而易见,两者并不相等。相同逻辑的函数被重复定义在了各自的实例对象上。这就造成了资源浪费。所以更好的解决方式就是定义在原型上,让所有实例共用一个方法。

我们来使用原型来重写上个案例:

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

Person.prototype.greet = function() {
	console.log(`Hello, My name is ${this.name}`);
};

lucy = new Person('Lucy');
lucy.greet(); // Hello, My name is Lucy

bob = new Person('Bob');
bob.greet(); // Hello, My name is Bob

console.log(lucy.greet == bob.greet); // true,我们发现两者相同,因为它们都是指向原型上的该方法。

构造函数、原型和实例的关系

要了解原型链,首先我们需要知道它们三者之间的联系。下面以一张图案帮助大家理解。
在这里插入图片描述
由上图可知,有两个两个东西,构造函数PersonPerson的实例father。这里面最重要的一点就是:
实例(father)上有一个属性(proto)指回Person.prototype 那么我们验证一下:

function Person() {}

lucy = new Person();
console.log(lucy.__proto__ === Person.prototype); // true

当然我们还看见,这个知不知道都行:
构造函数(Person)的原型对象(prototype)上有内部属性constructor和其他自定义属性,且constructor属性指回构造函数。想要验证的可以输入:console.log(Person.prototype.constructor === Person)自行验证。

原型链

结合以上知识我们现在知道原型是可以被实例共享的,那么如果原型是另一个实例呢?这其实就是原型链的基本构想。具体实现如下:

  function Person () {}
  Person.prototype.greet = function() {
    console.log(`Hello, My name is ${this.name}`)
  }

  function Lucy(name) {
    this.name = name
  }
  Lucy.prototype = new Person();
  Lucy.prototype.sayName = function() {
    console.log(this.name)
  }
  
  let lucy = new Lucy('lucy');
  lucy.sayName() // lucy
  lucy.greet() // Hello, My name is Lucy

总结:原型这一部分知识比较绕,想要更加深入的了解还要看更多专业书籍和文章。就拿JavaScript高级程序设计这本书来说,它里面这一部分知识使用了很大篇幅才讲完,我这短短的博客自然有很多不足之处,所以本文仅供参考。

参考文献: JavaScript高级程序设计(第四版),我买的纸质书,这里就不放链接了[dog]。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript中,每个对象都有一个隐藏的 `__proto__` 属性,它指向该对象的原型原型是一个普通的对象,它包含了共享属性和方法。当我们访问一个对象的属性或方法时,JavaScript引擎会首先在该对象本身查找,如果找不到,则会沿着原型链向上查找,直到找到该属性或方法,或者到达原型链的顶端(Object.prototype)。这个原型链的过程就是通过 `__proto__` 属性来实现的。 例如,当我们创建一个实例对象 `teacher` 时,如果 `teacher` 对象本身没有 `teach()` 方法,JavaScript引擎会通过对象的 `__proto__` 属性查找到 `Teacher.prototype` 的显式原型上,如果 `Teacher.prototype` 仍然没有该方法,它会继续沿着 `Teacher.prototype.__proto__` 找到 `Person.prototype`,直到找到 `teach()` 方法并执行。这样就形成了一个原型链。 同时,可以注意到 `Object.prototype.__proto__` 的值为 `null`,即 `Object.prototype` 没有原型。所以在原型链中,当找到顶层原型还没有属性时,就会返回 `undefined`。 需要注意的是, `__proto__` 是一个非标准的属性,实际开发中不应该直接使用它。它只是内部指向原型对象 `prototype` 的一个指示器,我们应该使用 `Object.getPrototypeOf()` 或 `Object.setPrototypeOf()` 来访问和设置对象的原型。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [JS:原型原型链](https://blog.csdn.net/elevenhope/article/details/122882582)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [JavaScript原型链(重要)](https://blog.csdn.net/liyuchenii/article/details/125957625)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值