上回介绍了如何使用建构式来建立原型,接着今天介绍使用 Object.create()
建立多层原型,先前在 T Shirt 例子有提到 , T Shirt 的原型是衣服,而衣服原型,仍然能有原型,这种多层原型就会使用 Object.create()
这个方法。
Object.create()
这个功能简单来说就是,建立一个新的原型物件,而这个原型物件是没有实体的,这边使用范例来观察
const Ryder = {
name:'Ryder'
}
const student = Object.create(Ryder)
console.log(student) //{}
student.name // Ryder
虽然 student
实体仍是空物件,但我们使用 student.name
可以看到他会回传 Ryder
这是因为 Object.create()
的功能,让 student
的原型继承 Ryder
的内容 ,可以点开 student
回传的空物件,看看他 [[Prototype]]
的结构:
这样便清楚 Object.create()
的功能其实就是能够让参数中的内容,成为目标的原型。
这边复制之前的 TShirt
程序码
function TShirt(color,material,size){
this.color = color
this.material = material
this.size = size
}
TShirt.prototype.clothe = function() {
console.log(`穿上 ${this.color} T Shit`);
}
const BlackTShit = new TShirt('black','棉','L')
目前是的原型链是
BlackTShit (子层) ⇒ TShirt (父层)
预期在 TShirt 上一层在新增一层 apparel
原型,也就是让原型链变成
BlackTShit ⇒ TShirt ⇒ apparel (服饰)
接下来就是新增 apparel
原型,并使用刚刚介绍的 Object.create()
, 让 apparel
成为 TShirt
的原型,以下是范例:
// 新的一层原型
function apparel(type){
this.type = type || 'T Shirt'
}
// 为新原型新增方法
apparel.prototype.mirror = function(){
console.log(`我穿着 ${this.color} 的 ${this.type} `)
}
function TShirt(color,material,size){
this.color = color
this.material = material
this.size = size
}
// 使用 Object.create 让 TShirt 原型继承 apparel 原型
TShirt.prototype = Object.create(apparel.prototype)
TShirt.prototype.clothe = function() {
console.log(`穿上 ${this.color} T Shit`);
}
const BlackTShit = new TShirt('black','棉','L')
在这段范例中要特别注意的是这一段:
TShirt.prototype = Object.create(apparel.prototype)
这边是让 TShirt
这个函式建构式的原型,继承了 apparel
函式就建构式的原型。
在完成上面使用 Object.create()
串连原型後,接着试者使用 mirror()
以及 clothe()
方法。
BlackTShit.clothe() //穿上 black T Shit
BlackTShit.mirror() //我穿着 black 的 undefined
可以发现在 apparel
这一层原型新增的方法虽然成功了, mirror()
方法中的 type
属性却无法正确显示,这是因为使用 Object.create()
让 TShirt
继承了 apparel
的原型,但却没有继承 apparel
的『建构函式』。
这时候需要在 TShirt
建构函式中使用 call()
方法,来让 TShirt
中的 this
绑定到 apparel
上,而这段其实就是将两个 建构函式 串接起来,并在传入 'T Shirt'
字串当作 apparel
的 type
参数。
function apparel(type){
this.type = type || '帽 T'
}
apparel.prototype.mirror = function(){
console.log(`我穿着 ${this.color} 的 ${this.type} `)
}
function TShirt(color,material,size){
apparel.call(this, 'T Shirt')
this.color = color
this.material = material
this.size = size
}
TShirt.prototype = Object.create(apparel.prototype)
TShirt.prototype.constructor = TShirt
TShirt.prototype.clothe = function() {
console.log(`穿上 ${this.color} T Shit`);
}
const BlackTShit = new TShirt('black','棉','L')
BlackTShit.mirror()
BlackTShit.clothe()
这样在 console 打上 BlackTShit
便会看到,来自 TShirt
原型 、apparel
原型上的完整属性以及内容了。
最後这边看起来程序码已经相当的完整了,但是如果要让原型链完整的话,其实还必须在 Object.create()
底下加上 TShirt.prototype.constructor = TShirt
,这是因为在 Object.create()
设定时就会将原本 TShirt
原型中的内容在加回来。
function apparel(type){
this.type = type || '帽 T'
}
// 为新原型新增方法
apparel.prototype.mirror = function(){
console.log(`我穿着 ${this.color} 的 ${this.type} `)
}
function TShirt(color,material,size){
apparel.call(this, 'T Shirt')
this.color = color
this.material = material
this.size = size
}
// 透过 Object.create() 为 TShirt
TShirt.prototype = Object.create(apparel.prototype)
TShirt.prototype.constructor = TShirt
TShirt.prototype.clothe = function() {
console.log(`穿上 ${this.color} T Shit`);
}
const BlackTShit = new TShirt('black','棉','L')
BlackTShit.mirror()
BlackTShit.clothe()
这样就是完整的让原型继承原型的方法了。
>>: [Golang] Custom Type Declarations and Struct
今天是最後一天,终於… 我选择最後能初探一下的,就是资料视觉化啦。 Kibana Visualize...
身为一个普大的普通大学生, 实战经验少得可怜, 除了学过资工基本学科,就只会用 Python 写 L...
一、介绍 这是 Obsidian 使用教学 — 插件篇的第 2 篇文章。 在 上一篇文章 中,我介绍...
记录可以少走一些坑 因为主管、同事的推坑陷害,背上莫须有的罪名,让你的分红考绩化为乌有,那你一定要观...
前言 在经过前面 9 天的准备之後,我们终於有些本钱可以涉足这个领域了,整理一下我们现在所掌握的 知...