白话 Javascript 原型

Posted by Sir0xb on 2019-08-303 16:05:15 +0800

如果你看过很多关于 Javascript 原型的文章,还没弄明白或曾经弄明白了现在又糊里糊涂不太清楚,那这篇文章很适合你。

我将用大白话讲讲什么是 Javascript 原型。那我们开始。


第一个吃螃蟹的大明星

曾经有个荒无人烟的小岛,虽然它从未有人涉足,但它却有一个响亮的名字 —— Javascript。

有一天有个叫 Object.prototype 的人登上了小岛,他通过自己的奋斗开垦了这座小岛,并在岛上建立了一家娱乐公司。

等公司有了一定规模,他想,作为一个公司的大老板他怎么能所有的事情都亲力亲为呢?!

于是他找了一个助理 Object 为他帮忙,并和他签署了法律合同,他也成功成为了岛上第一个大明星。

注意:

  1. 所有的明星都有 prototype 的姓氏。

  2. 所有的明星都会通过《经纪人合同 constructor》把自己的工作委托给经纪人。

  3. 当然,经纪人也要和 xx.prototype 明星签署一个代理协议 prototype 来帮助明星实现梦想。


另一个大明星

其实,Object.prototypeObject 两个人把这娱乐公司经营的已经很好了。但喜欢奋斗的 Object.prototype 怎么会甘于现状呢?

于是他有了个激进的想法 —— 为什么不把公司弄成明星工厂呢?

他们只要做好代理工作就可以了。于是,他请了另一个明星 Function.prototype

当然 Function.prototype 也有自己的经纪人 Function

现在,这座岛上已经有了两位大明星。

Function.prototype 登岛之日,Object.prototype 就拿着之前拟好的《签约合同 __proto__ 很轻松的完成第一份合同的签署。


稳步的发展

踏出了第一步,后续就容易了很多。岛上又请了好多明星,Person.prototype 和他的经纪人 Person 就是其中一对。

当然,合同签署方式跟之前是一样的,标准的《签约合同 __proto__

看着大老板轻松自在的挣着钱,Function.prototype 坐不住了,难道没有别的途径挣钱了吗? 既然可以通过跟岛上的所有明星签约挣钱,那是不是也可以通过跟岛上的所有经纪人签约挣钱呢?于是,他搞了一个经纪人注册事务所,跟岛上所有的经纪人签了《签约合同 __proto__

不过,钱也不是白拿的,Function.prototype 需要参加所有跟剧组的洽谈合作工作中,这个工作量也是蛮大的。


各种接活

虽然,岛上的经纪人们个个都很能干,但最令人瞩目的还是 Person

Person 为自己的明星 Person.prototype 接了一部电视剧和一部电影。

最终,公司的标准合作模式就形成了。


林子大了,各种奇怪的鸟

林子大了吧,什么样的鸟都有。

有些明星经纪人呢,做了个皮包公司,当然他身后也有一个名不见经传的明星,但实际业务都是直接找其他经纪人帮着解决。

我们看看这么一位明星经纪人 Student

function Student(name, age, sex) {
var obj = new Object()
obj.name = name
obj.age = age
obj.sex = sex
obj.sayName = function() {
return this.name
}
return obj
}

Student 呢就是 Student.prototype 明星的经纪人。看看他都干了啥。

接活的时候,私底下请了另一个经纪人 Object 以及他背后的团队来帮忙,自己代理的明星 Student.prototype 最后其实什么都没干。

当然合作方也不傻,最终合同上也是能看出到底是谁干的活:

当然,还有些聪明一点的。虽然,也是找别的经纪人帮忙,但是签合同的时候丝毫不马虎。我们看看 NewStudent

我们看看他是怎么做到的。

function NewStudent(name, age, sex) {
var obj = new Object()
obj.name = name
obj.age = age
obj.sex = sex
obj.sayName = function() {
return this.name
}
obj.__proto__ = NewStudent.prototype
return obj
}

也跟上一个经纪人一样,同样都是找 Object 帮的忙,但在结算的时候,是以自己代理的明星为中间人的。

当然,NewStudent.prototypeObject.prototype 的签约合同还是在的。


不同性格

function 实际上就是一个经纪人和其背后明星的一个小团队。因为是两个人,两个人的性格会直接影响到接的单子的结果。

我们先看一下,一个艺名叫 Test.X 的明星。

function Test() {}
Test.prototype.name = 'Test.X'
 
var test1 = new Test()
var test2 = new Test()

明星的艺名,如果剧组不改,每个剧组的默认明星艺名就沿用明星自己起的名字。

但,如果某个剧组觉得明星的艺名不好听,再起了一个新的。既不会影响别的剧组的艺名,也不会影响明星自身的艺名。

相当于,明星的性格是个剧组表现出来明星的默认性格。当然,导演也可以要求明星表现的不一样。

经纪人拟定的合作方式,会影响每个具体的剧组。但彼此剧组间独立,也不会直接影响到明星本身。

function HeyYo(name, age) {
this.name = name
this.age = age
}

明星公司的故事到此就差不多了。

其实,所谓继承也好各种模式也好,无非就是合同主体 __prop__ 不一样,不同的合同主体就决定了这部剧里都有哪些明星出演。

说回来就是会有哪些功能块会出现在链条中。知道了原理,再看开发模式就很好理解了。


创建对象的方式

1). 直接使用对象赋值或找经纪人 Object

var o1 = { name: 'o1' }
var o2 = new Object({ name: 'o2' })

这两种都是很好的跟明星 Object.prototype 合作的方式。

既能让明星 Object.prototype 出现在剧组,也能将合同的内容 { name: 'xx' } 体现到剧组中。

2). 找其他经纪人,例如:Person

function Person() {}
 
var o3 = new Person()

这种方式,剧组的主演肯定是 Person.prototype,当然,Object.prototype 也会参加剧组,只不过不是主演而已。

剧组 o3 的合同 __proto__ 签约的是 Person.prototype,所以他是主演。因为有了 Person.prototypeObject.prototype 之间的 __proto__ 签约关系,Object.prototype 也要参与剧组,只不过不是主演。

3). 找老板帮忙,请某位明星出演

function Person() {}
 
var o4 = Object.create(Person.prototype)

剧组跟某位明星不熟,所以请大老板出面,请某位明星帮忙出演某个剧组。


判断出演明星与主演明星的方法

既然剧组可以跟很多明星合作,因为有费用问题,必然要知道谁是主演,都有谁出演。

// instanceof 判断与某个经纪人背后的明星是否有合作
function Person() {}
 
var p = new Person()
 
instanceof Person // true
instanceof Object // true
 
// 判断主演,看直接合同明星的经纪人是不是当前经纪人
p.__proto__.constructor === Person // true
p.__proto__.constructor === Object // false

常用的合作方式,剧组有多个明星出演的情况

1). 合同拷贝,只是学习了某位明星的合作方式。

function Parent() {
this.name = 'parent'
}
 
function Child() {
// 直接复写了一遍 Parent 这位经纪人的合同
Parent.call(this)
this.type = 'child'
}
 
var c = new Child()

虽然剧组 cParent 经纪人的风格,但跟他身后的明星 Parent.prototype 没有任何关系。

2). 通过代理经纪人代理某位明星的剧组

function Parent() {
this.name = 'parent'
this.list =  [1, 2, 3, 4]
}
 
function Child() {
this.type = 'child'
}
Child.prototype = new Parent()
 
var c1 = new Child()
var c2 = new Child()

经纪人 Child 的代理明星,其实是 Parent 经纪人的剧组。

虽然,看着实现了“多明星合作”,可实际上只是装装样子而已。而且,如果某个剧组修改了主演的某些属性,会影响到其他剧组。

剧组的合作方式上主演像 Child.prototype 但实际上是 Parent.prototype

3). 经纪人直接找另一个明星代演

function Parent() {
this.name = 'parent'
}
 
function Child() {
Parent.call(this)
this.type = 'child'
}
Child.prototype = Parent.prototype
 
var c = new Child()

这种问题是,一开始洽谈的时候很好,Child.prototype 当主演,Parent.prototype 也加入演员团队。(继承继承,不就是要这个效果嘛)

结果可好合同条款加进去了 Child.prototype 却没出现在片场。

4). 培养新人方式

function Parent() {
this.name = 'parent'
}
 
function Child() {
// 抄袭了前辈的合同
Parent.call(this)
// 自己在稍微发挥一下
this.type = 'child'
}
// 带出了一个新明星,主要跟着 Parent.prototype 学出来的
Child.prototype = Object.create(Parent.prototype)
// 为他指定了经纪人
Child.prototype.constructor = Child
 
var c = new Child()

继承方式也就差不多这几种吧,面试应该是够了😂😂😂

- THE END -