【js进阶】-原型/原型链

news/2024/11/17 14:13:45/

一、构造函数创建对象

我们先使用构造函数创建一个对象,先来认识下构造函数

function Person() {
}
var person1 = new Person();
person1.name = '张三';
console.log(person1.name) // 张三

在这个例子中,Person 就是一个构造函数,我们使用 new 创建了一个实例对象 person1

prototype

每个函数都有一个 prototype 属性,它指向的是一个对象,既然它是一个对象,我们就手动给上面例子中的Person.prototype对象增加一个color属性:

function Person() {   //构造函数Person
}Person.prototype.color = 'white';   //给Person.prototype对象增加一个color属性
const person1 = new Person();   // 创建第一个实例对象person1
const person2 = new Person();  // 创建第二个实例对象person2
console.log(person1.color) // white
console.log(person2.color) // white

其实,函数的 prototype 属性指向的这个对象,正是调用该构造函数而创建的实例对象的原型(原型对象),也就是这个例子中的 person1 和 person2 的原型(原型对象)

那什么是原型呢?你可以这样理解:每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型中"继承"属性,就是因为会"继承"原型对象中的属性,所以上述例子中创建的两个实例对象person1和person2都默认拥有了color属性,这个color属性就来源于Person.prototype这个原型对象

让我们用一张图表示构造函数和实例原型之间的关系:
在这里插入图片描述
这时候,有部分思考的同学就会问了,那你刚才举的例子是通过构造函数创建的实例对象是这样的,那如果直接通过字面量的形式创建的对象也会是这样的吗?

好,我们就来看下:
在这里插入图片描述
上述代码可以看出通过字面量形式直接创建的对象obj,它也是"继承"其原型对象上的属性(toString),可能有些同学对于_proto_属性不太清楚,没关系,我们马上就讲,这里你只需要知道对象中的_proto_属性指向其原型对象就可以了,所以这也印证了之前说的那句话:每一个对象都会从原型中"继承"属性

_ proto _

这是每一个JavaScript对象(除了 null )都具有的一个属性,叫__proto__,这个属性会指向该对象的原型。

为了再次验证该说法,我们还是以第一个例子为例:
在这里插入图片描述
于是我们更新下三者(构造函数-原型对象-实例对象)的关系图:
在这里插入图片描述
既然实例对象和构造函数都可以指向原型,那么原型是否有类似属性指向构造函数或者实例呢?

constructor

每个原型对象都有一个 constructor 属性指向关联的构造函数。

function Person() {}
console.log(Person === Person.prototype.constructor); // true

所以再更新下关系图:
在这里插入图片描述

实例属性查询机制

读取实例的属性时,如果找不到,就会查找与该实例对象关联的原型中的属性,如果还查不到,就去找原型的原型,直到最顶层为止(Object.prototype)。

function Person() {    // 构造函数Person
}Person.prototype.color = 'white';
const  person1 = new Person();   //创建一个实例对象person1.color = 'black';   // 给该实例对象赋值一个color属性,值为black
console.log(person1.color) // blackdelete person1.color;   //删除实例对象上的color属性
console.log(person1.color) // white   

在这个例子中,我们给实例对象 person1 添加了 color 属性,当我们打印 person1.color 的时候,结果自然为 black。

但是当我们删除了 person1 的 color 属性时,读取 person1.color,此时person1 对象中找不到 color 属性时就会从 person1 的原型也就是 person1.__ proto __ ,也就是 person1.prototype中查找,幸运的是我们找到了 color 属性,结果为 white。

原型的原型是谁(最终源头是谁?)

我们知道原型对象其实也就是一个对象,那既然是对象它就是可以通过new Object()的方式来创建,所以原型对象其实就是Object的实例对象,所以上述例子中Person.prototype原型对象的原型就是Object.prototype

function Person() {    // 构造函数Person
}
Person.prototype.__proto__ === Object.prototype    // true

在这里插入图片描述

原型链

那 Object.prototype 的原型呢?

是null,我们可以打印看看:

console.log(Object.prototype.__proto__ === null) // true

所以 Object.prototype._ proto _ 的值为 null 跟 Object.prototype 没有原型,其实表达了一个意思。所以查找属性的时候查到 Object.prototype 就可以停止查找了。

最后一张关系图也可以更新为:

在这里插入图片描述
其实上图中由相互关联的原型组成的链状结构就是原型链,也就是蓝色的这条线。

特殊注意点

1、我们看个例子:

function Person (){}
const person3 = new Person();
person3.constructor === Person   

上面例子中可以看出创建的实例对象中也有constrctor属性,它也是指向创建它的构造函数,看到这有些同学有点蒙了,刚才不是说原型对象中有一个constrctor属性指向构造函数吗?现在怎么实例对象中也有该属性,怎么这么乱呢?

其实这里的constructor属性就是"继承"原型对象中的constructor属性,实例对象本身没有该属性,它自身没有就会去它的原型对象中找,这样解释是不是就立马通顺了…

person.constructor === Person.prototype.constructor   // true

2、全篇一直对于"继承"这个词语用引号括起来了,这是因为这种说法并不恰当,因为继承意味着复制操作,然而 JavaScript 默认并不会复制对象的属性,相反,JavaScript 只是在两个对象之间创建一个关联,这样,一个对象就可以通过委托访问另一个对象的属性和函数,所以与其叫继承,委托的说法反而更准确些。


http://www.ppmy.cn/news/484825.html

相关文章

JS原型、原型链到底是什么?

前言 在js的学习中,原型毫无疑问是一个难点,但也是一个不可忽视的重点。在前端面试中也是一个高频考题,在接下来的深入学习中,你会发现原型、原型链等知识点其实并不难。 1. “一切皆为对象” JavaScript是一个面向&#xff08…

原型及原型链 ①

文章目录 原型及原型链函数对象constructor 构造函数new 操作符将构造函数当作函数构造函数的问题prototype 原型理解原型对象更简单的原型语法原型的动态性原生对象的原型原型对象的问题构造函数和原型结合构造函数和原型结合 __proto__原型链关卡 本文转:https://…

原型原型链深度解析

原型 原型是函数特有的,构造函数制造出对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。 我们先写一个构造函数 function Person() {} var person new Person(); person.name luoxi; console.log(person.name) // luoxi在这…

原型,原型链,原型的继承

原型的作用? 1.节省内存空间 2.实现数据共享(继承) 什么是原型? 任何一个函数都有propotype属性,它本身是一个对象,我们称之为原型 构造函数,实例化对象与原型之间的关系? 1.任何一个函数都有prototype属性,它本身是一个对象,我们称之为原型 2.构造函数也是函数,也都…

原型和原型链详细讲解

目录 一、构造函数 二、原型对象 三、原型链 四、函数也是一种对象 五、总结 一、构造函数 构造函数、普通函数区别,使用new关键字创建对象的函数叫构造函数。构造函数的首字母一般是大写,用以区分普通函数。 function Person(name, age) {this.nam…

硬核!原型和原型链详解

前言 我是歌谣 知其然知其所以然 人人都有一个大厂梦 希望通过自己的一个总结分享可以给予大家带来帮助和提升。 本期知识点 原型和原型链 目标 1理解原型和原型链 2理解构造函数 3理解构造函数 原型和原型链之间的关系 引用类型都是对象 基本数据类型和引用数据类型可以看下…

【原型和原型链】什么是原型和原型链

一、原型 ①所有引用类型都有一个__proto__(隐式原型)属性,属性值是一个普通的对象 ②所有函数都有一个prototype(原型)属性,属性值是一个普通的对象 ③所有引用类型的__proto__属性指向它构造函数的prototype var a [1,2,3]; a.__proto__ Array.pro…

原型链详解

什么是原型链 原型链就是顺着__proto__所在的一条链子,这样说可能不是很好理解,下面来看例子你就会理解。 需要了解 1.a.__proto__和 a.prototype都称做为a的原型。 2.Object.prototype是原型链的顶端。 3.如果 a是由b实例化出来的,则有关…