原型与原型链

今天看了github上面的某位大佬对原型与原型链的文章 讲解很透彻 文章下面贴地址

prototype

每个函数都有prototype属性,如下

这个函数的prototype到底是什么呢,是函数的原型吗?

其实,函数的prototype都会指向一个对象,这个对象 就是调用改构造函数而创建的实例的原型,也就是上图的a b的原型

什么是原型呢?

每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性。

用过一张图来表示构造函数与实例之间的关系

那么上面的变量 ab是怎么访问到score的prototype.name的呢?

这里就要提出第二个属性

___ proto ___

这是每个JavaScript对象都会有的属性 叫做_ proto _ 这和属性 指向该对象的原型 即是

function score () {}
score.prototype.name = "张三"
var b= new score()
b.__proto__.name   //"张三"

这里可以看到 b._ proto_ 是指向score.prototype的 或者我们可以证明

score.prototype == b.__proto__  //true

现在我们知道

构造函数 prototype 指向原型 构造函数可以生成实例 实例的 _ proto _ 指向原型

于是关系图可以这么理解

这里构造函数 和 实例都指向 原型 那么会不会有 原型指向构造函数与实例呢?

constructor

没有指向实例的方法 因为 会有多个实例 但是有指向构造函数的方法 就是constructor 每个原型都有一个constructor属性指向关联的构造函数

可以看出来constructor指向构造函数本身

总结一下 现在得出结论

3

console.log(score.prototype.constructor == score)
console.log(score.prototype == a.__proto__)

再更新一下图

实例与原型

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

function score () {}
score.prototype.age="20"    //在原型链上面赋值 age = 20
var a = new score()
a.age
"20"      //age指向原型链上面
a.age= "10" 
"10"      //这时候指向a实例上面
delete a.age;
a.age
"20"     //age指向原型链

当实例没有age这个属性 他会在原型链上面找

当给实例赋值的时候 就会覆盖prototype上面的属性 但是 prototype上面的属性依旧存在

当将实例上面的age删除的时候 就会依旧打印出原型链上面的属性

这里思考一个问题 JavaScript万物皆对象 name prototype的对象是什么呢?

原型的原型

我们已经讲了原型也是一个对象,既然是对象,我们就可以用最原始的方式创建它

Object.prototype.name = "张三"
var obj = new Object();
console.log(obj.name) // 张三   //和上面同理 来自原型链上面的name
Object.prototype.constructor == Object

现在关系图再次更新

原型链

那 Object.prototype 的原型呢?

console.log(Object.prototype.__proto__)
null

null 表示“没有对象”,即该处不应该有值

所以 Object.prototype.proto 的值为 null 跟 Object.prototype 没有原型,其实表达了一个意思。

最后整理关系图

图中由相互关联的原型组成的链状结构就是原型链,也就是蓝色的这条线。

最让人不注意的就是日常引用要注意的问题

首先 看下面代码

function score () {}
var a = new score()
console.log(a.constructor == score)

答案是 true

当获取 a.constructor 时,其实 a中并没有 constructor 属性,当不能读取到constructor 属性时,会从 a的原型也就是 score.prototype 中读取,正好原型中有该属性,所以相当于:

person.constructor === Person.prototype.constructor

学过java的人可能会将JavaScript的原型链理解为继承 但是 JavaScript里面一直以来都没有这个说法

你不知道的JavaScript 里面有一句话

继承意味着复制操作,然而 JavaScript 默认并不会复制对象的属性,相反,JavaScript 只是在两个对象之间创建一个关联,这样,一个对象就可以通过委托访问另一个对象的属性和函数,所以与其叫继承,委托的说法反而更准确些。

原型与原型链

原文地址:https://www.cnblogs.com/wuvkcyan/p/8955353.html