一、对于prototype的初步认识
对于JS而言一切皆为对象,那么创建对象是通过原型链的方式进行创建的(原型模式)。由于最近在细挖js的基础知识,让本人更能够深层次地去理解js地底层原理,为了提升自身的技术能力,需要接触理解原型链的原理。
1.1 什么是原型?什么是原型链?
在js中大部分的构造函数以及对象都是有prototype的属性,这是就是原型对象。再此之上,构建构造函数new实例化之后的对象与原型之间的关联线,叫原型链。
1.2 为什么需要使用原型链?
这样可以实现继承效果,每次构造函数的new实例化都会指向原型对象中,这样它们都有公共的属性以及方法,这样可以减少代码的占用空间。
只要属性以及方法都存在与原型链上都可以访问到。当我们需要使用原型链的一个变量时,它会先查找当前一层,未找到的话跳到上一层,直至找到为主。(要是未找到的话,直接报错)
1.3 原型链三角关系图
1.3.1 .__ proto __ 与 .prototype的区别
观察到上图会发现两种访问原型对象的途径,现在来看看两者之间的区别:
- .__ proto __ 是实例后对象所指向的原型对象,为隐式原型。
- .prototype 是构造函数所指向的原型对象,为显式原型(只有构造函数才拥有)。
1.3.2 使用浏览调试器观看原型链的层与层之间的关系
我们先定义一个构造函数A,实例化后为实例C,并打印看出C的原型对象,并观察它一层层的原型对象。
<script>
export default {
data(){
return{
}
},
mounted(){
this.seePrototype()
},
methods:{
seePrototype(){
function A(){}
let C = new A()
console.log('c',C)
}
}
}
</script>
控制台显示
可以看出原型链的层层相关,并最终找到Object的原型对象,而它的指向的隐式原型为null。
1.4 原型链在平时编写js可以怎么使用?(结合本人目前碰到)
- 判断该对象是什么类型(变量的隐式原型 与 构造函数的显示原型比较,既是instanceof)
变量.__ proto __ === Array等构造函数.prototype (简写 变量 instanceof Array等构造函数) - 打印出该对象的类型
Object.prototype.toString.call(变量)
1.5 原型对象的引用值是有共享(继承性的特征),那么修改它子类原型对象的引用值,会发生什么情况?
相关代码:
<script>
export default {
data(){
return{
}
},
mounted(){
this.checkPrototype()
},
methods:{
checkPrototype(){
//第一层 构造函数SuperType定义
function SuperType(){
this.num = ["1", "2", "3"];
}
//第二层 构造函数outSide定义
function outSide(){}
outSide.prototype = new SuperType()
//实例化第二层函数outSide(instance1)
let instance1 = new outSide();
console.log('instance1',instance1)
// 修改第一层的原型对象的引用值
instance1.num.push('4')
console.log(instance1.num)
//实例化第二层函数outSide(instance2)
let instance2 = new outSide();
console.log('instance2',instance2)
console.log(instance2.num)
},
}
}
</script>
运行截图:
由上述情况可以看出,我们在子类outSide原型对象中的父类SuperType原型对象,若对子类SuperType进行传参,会影响该原型链下的所有实例。(不管父类outSide原型对象在哪里多次实例化)
具体原型链更深层次的探讨之后会抽空认真再学习,这样才能研究透彻。