李恒道 发表于 2021-7-16 22:02:25

[油猴脚本开发指南]原型与原型链

# FBI WARNING

本文为了符合行文逻辑以及阅读理解,并由于个人的编程功底问题,存在事实性错误,仅供理解参考,与实际可能不符

# new与函数this

在之前我们已经学习了this,在这节课我们聊一聊一个JS中极其复杂的概念,原型与原型链

首先我们提出一个问题,假如我想创建上百个对象,我们该怎么做?

```
function createObeject(name){
    var retobk={}
    retobk.name=name
    retobk.eat=function(){
      console.log(this.name+'吃东西')
    }
    return retobk
}
var a=createObeject('多来CC梦')
var b=createObeject('多来DD梦')
a.eat()
b.eat()
```

我们可以考虑搞一个函数,这个函数负责返回一个对象内容,但是这样很麻烦,而且并不直观,不够简洁漂亮,让我们来看看更简洁的写法!

```
function createObeject(name){
    this.name=name
    this.eat=function(){
      console.log(this.name+'吃东西')
    }
}
var a=new createObeject('多来CC梦')
var b=new createObeject('多来DD梦')
a.eat()
b.eat()
```

我们把函数内的变量取消了,所有的数据都存到了this上,但是这个时候大家可能有疑问,这个this是什么?这个函数里的this需要与new进行联合使用,当我们调用new createObeject的时候,new就会自动创建一个对象,并且将this绑定到对象身上来完成接下来的赋值!

# 对对象函数进行简化

其实尽管上面的我们可以使用,但是依然存在一个巨大的问题,就是这个函数是属于对象自身的,创建一个两个还好,但是如果我们重复创建上万个同样的对象,这同样的对象里包含了同样的一个重复的函数,太占用空间了,也太离谱了不是么?

那我们有什么解决的措施?我们可以对所有函数new出来的对象分配出一个相同的空间,让这个空间来存放一些相同的函数以及数据,用来节省空间。

这个空间的名字就是proto(原型)

对象1---proto--------↓

对象2---proto--→共享空间

对象3---proto--------↑

那做到这里我们的问题已经解决一大步了,接下来我们继续推演,现在对象有共享的空间了,那我们在创建函数的时候,也要可以触及到共享的空间,这样才能使我们在写创建对象的函数代码的时候,把我们的一些函数放到共享的空间里。所以函数里存在一个prototype,用来指向共享空间。

对象2---proto--->共享空间<----prototype----函数

那还有一个问题就是,我们该怎么知道哪个对象是由哪个函数构造出来的?我们可以给对象包含一个数据,这个数据指向函数,但是如果构造成千上万个对象,又包含成千上万个数据!太麻烦了,所以我们把这个引用也放到共享空间上

![图片.png](data/attachment/forum/202107/16/221835jr8mmphwhwk8f22e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

那么到这里,你大概理解了一个函数的原型,我们开始加速了,车门已经焊死了!

JS有一个很有趣的地方就是,万物皆对象,就是一切都是一个对象类型

我们的共享空间以及函数也不例外

我们分别来观察共享空间以及函数吧

首先让我们看看共享空间

共享空间也是一个Object类型的对象,所以根据我们上述的

共享空间也具有proto,constructor以及prototype不过分吧

![图片.png](data/attachment/forum/202107/16/222419sg0r5t7577q7zx7t.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

现在的图就变成了这样,共享空间对象也具有一个共享空间,也具有函数,因为共享空间是一个对象,所以构想空间的constructor就是对象函数,是Object(),并且因为这里的共享空间对象再往后的共享空间还是一个object,就形成了无限套娃,所以我们通常在共享空间对象的共享空间就设置为null了

![图片.png](data/attachment/forum/202107/16/222630rrna4zjs4i9jeqsz.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

这里共享空间对象的这部分就算讲述完毕了,接下来我们看函数的脉络

由于JS万物皆对象的概念,函数也是一个对象,那他也应该具备共享空间,

那他也应该具有构造函数,他的构造函数是什么呢?因为他是一个函数类型,所以构造他的就应该是一个Function

![图片.png](data/attachment/forum/202107/16/223228hgccaaeenaa6lwiz.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

函数的共享空间依然是对象,所以跟之前的逻辑一致

function Function的共享空间依然指向函数的共享空间,因为共享空间Object是一个顶级,而函数不属于顶级,所以function Function依然可以指向共享空间

![图片.png](data/attachment/forum/202107/16/223451bjuo82wufz8fsfow.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

而之前构造共享空间的函数function Object也是一个函数,也要指向函数的共享空间

![图片.png](data/attachment/forum/202107/16/223550spp4odsdpqp9sspd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

到这里就基本讲完了,但是还有最后一点需要注意,就是函数的共享空间与共享空间对象的共享空间是属于同一共享空间,因为函数的共享空间是对象,而共享空间对象的共享空间依然是一个对象,所以他俩的共享空间应该属于同一个共享空间。

这里原型和原型链的概念就讲述完毕了,我们可以看一下网络上一张较为清晰的图

![图片.png](data/attachment/forum/202107/16/224024zzcqgmtg5becb5gc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

懒男孩 发表于 2021-7-16 23:15:45

ggnb!ggnb?

wonhurry 发表于 2021-7-17 09:56:03

每个字、每个单词都看得懂,但人已经晕了{:4_88:}。
弱弱的问一下,是构造出来的局部函数和对象指向同一个共享空间,还是全局函数和对象都指向同一个共享空间?

李恒道 发表于 2021-7-17 13:29:03

wonhurry 发表于 2021-7-17 09:56
每个字、每个单词都看得懂,但人已经晕了。
弱弱的问一下,是构造出来的局部函数和对象指向同一个 ...

function aa(){}
function bb(){}
aa.prototype.__proto__===bb.prototype.__proto__为true
因为共享空间都是一个Object()构造的 那共享空间的共享空间都是相等的

xxhuiuna87 发表于 2021-10-1 21:20:27


ggnb!ggnb?

李恒道 发表于 2021-10-1 21:33:17

xxhuiuna87 发表于 2021-10-1 21:20
ggnb!ggnb?

也有视频版教程的
哥哥有兴趣可以去b站看

国强张 发表于 2022-10-25 15:05:10

李恒道 发表于 2021-7-17 13:29
function aa(){}
function bb(){}
aa.prototype.__proto__===bb.prototype.__proto__为true


感觉像在讲引用对象和内存地址值

李恒道 发表于 2022-10-25 16:18:29

国强张 发表于 2022-10-25 15:05
感觉像在讲引用对象和内存地址值

是的,都一样的

xiaooooooo 发表于 2023-8-9 17:06:00

很好 重新定义了【较为清晰】
whatever ggnb!
页: [1]
查看完整版本: [油猴脚本开发指南]原型与原型链