js 原型链

作者: 木木心丶 | 来源:发表于2020-07-04 22:15 被阅读0次

什么是原型链?

我们先看一下下面的这个小例子:

let data = {
    name:'merit'
}
alert(data)

这时候,弹出的窗口里面显示着 [object Object],相信大家应该也都见过这个,可是为什么会是这个呢?

其实,再用alert显示对象的时候,会默认调用对象的toString函数,可是,我们明明没有给data设置这个函数啊,那这个函数又是哪里来的呢,这时候我们就把整个data给打印一下看一看:

我们看到,data不止有我们设置的name属性,还有一个我们没设置的__proto__属性,那这属性里面又是些什么东西呢,让我们再打开看一下:

1593426483110.png

这时候我们就在里卖弄看到了我们用到的toString函数。

上面这个是直接创建了一个Object实例对象,下面让我们用构造函数创建一个对象,看看是什么效果:

function MyObj(name){
    this.name = name
}
MyObj.prototype.myToString = function(){
    console.log(this.name)
}
let bar = new MyObj('merit')
alert(bar)

结果显然是和上面的一样为 [object Object],我们来看一看这个的toString方法是怎么得到的:


我们可以看到,bar这个对象本身有一个__proto__属性,这个属性里面竟然还有我们通过MyObj.prototype.myToString定义的函数,这个我们一会儿再说。然后在这个__proto__属性中,还有一个__proto__属性,里面有着我们所需要的toString函数。

当我们调用对象的某个属性的时候,就会先去看它本身有没有这个属性,没有的话,就会去看他的__proto__中有没有这个属性,有的话就调用,没有的话就继续看这个__proto__中的__proto__里面有没有,只到最后一层,如果都没有的话,才会报错。

上面这个例子中,如果把myToString函数名换成toString,那么alert(bar)再调用bar.toString就是我们自己写的内容了。

这种通过__proto__属性一层层的连接形成了一个链的样子就叫做原型链。

prototype与_proto_的关系

当我们创建一个对象的实例的时候,实例本身就会自带一个__proto__属性,该属性指向其构造函数的prototype属性,而所有构造函数的prototype属性都是一个Object的一个实例。而这个实例就会有一个指向Object.prototype的_proto__,所有对象类型无论是Array,String还是Function,最终的__proto__指向都是这个位置。

明白了原型链,其实就能够理解很多的东西了,比如我们经常使用的instanceof判断类型和实现继承的一些方式。

instanceof

我们经常使用instanceof去判断一个数据的数据类型,其实A instanceof B的本质就是去判断A这个对象的原型链上是否有B.prototype。这样你就能很好的明白下面的一些结果了:

let bar  = 'merit'
let bar_s = new String('merit')
let bar_a = [1,2,3]
let bar_f = function(){console.log(1)}

bar instanceof Object //false
bar_s instanceof String //true
bar_a instanceof Array//true
bar_f instanceof Function//true

//任何对象类型的原型链终点都指向到Object的prototype
String instanceof Object//true
Array instanceof Object//true
Function instanceof Object //true
Object instanceof Object //true

Object instanceof Function //true
String instanceof Function//true
Array instanceof Function //true
Function instanceof Function //true
//对于最后一组,我们要知道{},[]创建对象或数组都是new Object()/new Array()的语法糖,而Object,Array本身这些构造器,又都是Function的一个实例。

既然对instanceof的原理理解了,我们也可以简单的写一个简易版的instanceof

//myInstanceof
function myInstanceof(A,B){
    while(A.__proto__){
        if(A.__proto__===B.prototype){
            return true
        }
        A=A.__proto__
    }
    return false
}

继承

通过对原型链的理解,我们就可以很好的实现继承了。

function Parent(value){
    this.tag='我是父对象'
    this.val = value
}
Parent.prototype.showVal = function(){console.log(this.val)}

组合继承

function Child(value,name){
    Parent.apply(this,value) //通过这一步可以保证子对象里面有父对象的值
    this.tag = '我是子对象' //会覆盖掉父对象的赋值
    this.name = name;
}
//接下来我们要保证子对象能调用父对象的方法
Child.prototype = new parent()
Child.prototype.constructor = Child 
let bar = new Child('111','merit')

虽然我不知道为什么这个名字叫做组合对象,但是原理还是很明显的,就是让子对象的prototype指向父对象的一个实例,然后利用这个实例的__proto__去调用父对象的方法,下面一张图应该能很详细的说明这一点

通过上面这个图,我们可以看出子对象的一个实例bar是如何调用父对象的方法的,但是我们也能够看出来一个问题,就是通过这种构建一个父对象的实例在中间进行过渡的方式,会造成内存的浪费,因为我们并不会使用到父对象里面的值,这时候我们就可以通过下面的继承方式来改善

寄生组合继承

function Child(value,name){
    Parent.call(this,value)
    this.tag='子对象'
    this.name = name
}
//这个会创造一个__proto__指向Parent.prototype的空对象
let childPrototype = Object.creat(Parent.prototype)
childPrototype.constructor = Child
Child.prototype = childPrototype

通过创建父对象实例而是通过Object创建空对象的方式继承,就很好的解决了上面的问题,可以说是一种比较完美的继承方案了。

相关文章

  • 廖雪峰JS小记

    (function(){})() 原型,原型链 浅谈Js原型的理解JS 原型与原型链终极详解 对象 对象:一种无序...

  • JS的__proto__和prototype

    最近在回顾JS的原型和原型链的知识,熟悉JS的同学都知道JS的继承是靠原型链实现的,那跟原型链相关的属性__pro...

  • Javascript(三)之原型继承理解

    进阶路线 3 原型继承 3.1 优秀文章 最详尽的 JS 原型与原型链终极详解 一 最详尽的 JS 原型与原型链终...

  • 从实现角度分析js原型链

    从实现角度分析js原型链 欢迎来我的博客阅读:《从实现角度分析js原型链》 网上介绍原型链的优质文章已经有很多了,...

  • JS原型链

    1什么是JS原型链? 通过__proto__属性将对象与原型对象进行连接. 1.1 JS原型链的作用? 组成的一个...

  • 关于JS中的原型和原型链

    目录 关于js 对象和原型 原型链 基于原型链的继承 参考资料ECMAScript 6 入门JavaScript原...

  • js_继承及原型链等(四)

    js_继承及原型链等(三) 1. 继承 依赖于原型链来完成的继承 发生在对象与对象之间 原型链,如下: ==原型链...

  • 2022前端高频面试题

    JS相关 1.原型和原型链是什么 原型和原型链都是来源于对象而服务于对象的概念js中引用类型都是对象,对象就是属性...

  • JavaScript原型链

    js原型链 原型链是JS面向对象的基础非常重要 所有对象只有__proto__属性,而函数具有prototype属...

  • web前端面试之js继承与原型链(码动未来)

    web前端面试之js继承与原型链(码动未来) 3.2.1、JavaScript原型,原型链 ? 有什么特点? 每个...

网友评论

    本文标题:js 原型链

    本文链接:https://www.haomeiwen.com/subject/akmntktx.html