一篇文章,让你彻底理解原型和原型链

前言

在JS中,只要是一个函数,那么它就有prototype这个属性,该属性会指向一个对象,这个对象可以存放该函数定义的属性方法,并且这些属性和方法都是共享的,每个实例成员都可以使用这些属性和方法,这就是原型也被称为原型对象。

邂逅原型

既然原型如此强大,那么就让我们和它来一场美丽的邂逅。

我们创建一个构造函数,并往该函数的原型添加一些方法。

function User(name, age){
	this.name = name
	this.age = age
}
// 给User的原型添加方法
User.prototype.sayHi = function() {
	console.log(`你好,我是${this.name},我今年${this.age}岁了`)
}

// 创建两个实例对象,并且调用原型上面的方法
const zs = new User('张三', 18)

const ls = new User('李四', 19)

// 张三调用这个方法
zs.sayHi() // 你好,我是张三,我今年18岁了

// 李四调用
ls.sayHi() // 你好,我是李四,我今年19岁了

如代码所示,张三和李四都可以调用原型的sayHi方法,并且输出内容不一,这段代码足以体现出原型对象上面的方法是共享的。

为什么实例可以访问原型对象

你肯定有疑惑,为什么实例成员可以访问原型对象上面的方法,实例只是被new出来的对象,跟原型有什么关系呢?

// 打印一下上面new出来的实例对象
console.log(zs)

为了让大家方便观看,我把打印结果截图放出来。

在这里插入图片描述
先不要看其他代码,你就看__proto__,它是一个属性,听清楚!它会指向prototype原型对象,所以说,为什么实例对象可以访问原型对象了,就是有__proto__属性的存在,你也可以把它称之为对象的原型,总之,它的作用很强大。

用一段代码来证明我说的是否正确。

console.log(zs.__proto__ == User.prototype); // true

访问结果为true,足以证明,__proto__确实是指向了该函数的原型对象。

原型、constructor之间的关系

既然是往原型对象上面添加的方法,那么这些方法最终是属于谁的?总得给个说法,对吧?这是一个值得的思考的问题。

我们打印一下该函数的原型,便可得出结论。

console.log(User.prototype)

贴出一张图,方便大家观看。

在这里插入图片描述
可以看到,有一个sayHi函数,这个便是我们刚刚添加的方法。还可以看到一个constructor函数,它指向了一个函数,这个便是我们创建的这个User函数。

用一段代码来验证一下。

console.log(User.prototype.constructor == User) // true

打印结果为true,得出结论:原型对面里面的constructor函数用于指回我们最开始创建的那个构造函数,比如,你爸妈把你生下来,然后因为要工作,所以把你托养在外婆或者爷爷奶奶那,但最终你还是你爸妈的儿子和女儿,这是不可以改变的关系。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页