如何定义自己的原型
在这边我们定义了两个物件,等等我们会用建构式的方式产生这两个物件,并且这两个物件继承同一个原型。
情境呢跟上一篇文章一样,我们是造物主,我们必须在脑海中先有狗的原型,然后创造出两支狗,一只叫比比,一只叫噗噗。
var Bibi = { name: '比比', color: '棕色', size: '小', bark: function () { console.log(this.name + '吠叫'); }};var Pupu = { name: '噗噗', color: '白色', size: '大', bark: function () { console.log(this.name + '吠叫'); }};
可以注意到这两只狗都具有吠叫的方法,也就是说这个方法我们可以定义在这两只狗的蓝图上,也就是他们的原型函式。
那么我们就来定义吧!
我们再定义属性的时候,会利用 this.属性名称 = 属性
的方式定义,这样在使用 new 的时候就可以客製化的传入不同的进近来,赋予不同的属性内容。
function Dog (name, color, size) { this.name = name; this.color = color; this.size = size;}
所以一开始会是这样~!
现在 Dog 的函式只是一个蓝图,它并不是一个实体,要让它变成实体我们就需要使用到 new 的这个运算子。
那么首先我们先来看一下这个运算子的相关文件
MDN 的文件这边提到,使用 new 运算子会产生一个 Javascript 的物件,并且会连结回原本的物件(在这边的例子也就是指说被 new 出来的实体会连结到原本的 Dog 的函式)。
另外也会把 this 指向到新产生的实体上。
那我们就直接来实际做做看!
function Dog (name, color, size) { this.name = name; this.color = color; this.size = size;}var Bibi = new Dog('比比','棕色', '小');console.log('Bibi', Bibi);
运行结果如下:
可以看到印出来之后,展开 Bibi 的 proto
之后,其中的 constructor 属性指向了 Dog 的函式。代表这个物件是由 Dog 这个函示所创建的!
那么再来我们一样创建噗噗这只狗
var Pupu = new Dog('噗噗','白色', '大');console.log('Pupu', Pupu);
好~现在我们两只狗都创建出来了,但是你会发现还少了吠叫的方法。
这时候就要用我们上一篇文章提到的 prototype 的方法将共用的函式方法挂载到 原型上,也就是 Dog 的原型。
首先我们先 console.dir(Dog);
观察一下狗这个函式,我们之前也有说过,函示本身就是一个物件。
所以函式里面有一个通用的属性叫做 prototype,
透过 prototype 所新增的方法呢,就会作为原型上的属性,可以被向下的其他原型或是实体给取用到。
所以我们就透过将 bark 这个函式挂载在 Dog 这个原型的 prototype 上:
function Dog (name, color, size) { this.name = name; this.color = color; this.size = size;}// 多了这里喔!!!!!!!Dog.prototype.bark = function () { console.log(this.name + '吠叫');}// 多了这里喔!!!!!!!var Bibi = new Dog('比比','棕色', '小');console.log('Bibi', Bibi);var Pupu = new Dog('噗噗','白色', '大');console.log('Pupu', Pupu);
之后点开来看,这两只狗都可以找到 bark 的吼叫功能。
那么我们就实际的来吼叫看看!!
Bibi.bark();Pupu.bark();
好~到这边我们来总结一下,Dog 这个函式又被称为建构函式,用于建构其他实体所用的。
而为什么我们需要把 bark 的方法挂载在 Dog 的 prototype上呢? 主要是因为如果一直撰写在不同的物件中,会消耗记忆体的容量,当你需要记载的函式越来越多的时候,记忆体的负担就会更大。
所以透过统一挂载在 Dog 的 prototype上,可以提高效率,也方便作修改,一次只要调整一个地方就好,对于程式码来说也是很好维护的做法。
那么在这边在说明一件事,上一篇文章我们是直接将方法挂载在 proto
的属性上,但其实这个属性是用来指向该物件的原型是谁的一个属性。
如果我们要将共用的函式挂载在原型上的话,最好还是使用
建构函式名称.prototype.共用函式名称 = function (params) { ...}
这样的方法会比较好喔!
虽然呢
console.log(Dog.prototype === Bibi.__proto__); // true
这样两个内容式一样的,但还是希望大家使用 prototype 去挂载需要用到的共用函式,同时你在除错的时候,也比较容易找到问题点在哪里喔!
今天就先这样啦~希望这篇文章对大家有帮助~汪汪!