快三竞猜网站建设全球网站流量排名查询
有必要重新审视js原型链
经大量资料查找之后自我理解的总结:
一说原型有太多的总结,把我都给劝退了,太多所谓的名词:constructor | proto | prototype | Object.prototype | Function.prototype | new
从js的底层来理解,其实js中是没有class的,它跟java不同,而ES6中的class不过也只是原生底层构造函数(new 函数名)的语法糖罢了。
它出现的目的就是为了实现构造函数中的数据共享,防止资源浪费,所以才会为构造函数设置一个Prototype属性,把所有实例的对象共享为一个prototype对象,prototype好像是实例的原型,而实例对象好像继承了prototype 。
原型链的概念:实例对象和原型对象之间的链接,每一个对象都有原型,原型本身又是对象,原型又有原型,以此类推形成一个链式结构.称为原型链。
在js中通过【原型链】的机制,将上下关系串起来,当在A找不到某个东西时,就会去A的parent(也就是A.proto)中去找,还是找不到就再向上找,Prototype的顶部时Object.prototype,再往上就是null
prototype(原型)来实现构造函数中的数据共享。
语法:函数名.prototype = { 属性名:属性值 }
总结:由于所有的实例对象共享同一个prototype对象,那么从外界看起来,prototype对象就好像是实例对象的原型,而实例对象则好像"继承"了prototype对象一样
知识延伸: 原型链的[[prototype]]和__prototype__的知识点:【注意代码中的重点】
function Test (name) {return this.name = name;
}Test.prototype.foo = function () {
console.log(`大家好,我是${this.name}`)
}let bar = new Test('小明')/*** 这样的写法是错误的,因为prototype只能在原型的构造函数中* 使用ptototype来定义共享数据,而在使用new 构造函数后的对象中* 就会报错,不支持使用这种方式。* * 那为什么__proto__这个方法就能行,但数据还能跟其他一起使用相同* 构造函数的对象进行共享那?* ** 因为__proto__并不存在于我们当前的正在使用的对象中,而是“* 神奇地”引用了内部的[[prototype]]对象中* * */// bar.prototype.barFoo = function () {
// console.log(`${this.name}, 请你把作业交给我好吗?`)
// }// 实际上这里定义的就是Test构造函数中的公共对象
bar.__proto__.barFoo = function () {console.log(`${this.name}, 请你把作业交给我好吗?`)
}let baz = new Test('张凯');
bar.barFoo()
baz.barFoo()
console.log(bar, baz)