行为委托
Posted boses
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了行为委托相关的知识,希望对你有一定的参考价值。
什么是行为委托?
简单来说就是一种设计模式,不同于传统的构造函数的“类”式设计。
在这之前先说一下原型的基本知识。
什么是原型?简单来说就是一个对象内部关联另外一个对象,本质来说就是对象与对象之间的关联;
一个对象本身没有属性或者方法会到原型对象上查找。
这里每个例子会通过构造函数,class和行为委托来不同实现,不过不会评论class,是否使用class取决于你的观点。
先看一个例子,构造函数写法
function Foo(name) { this.name = name; } Foo.prototype.age = function() { console.log(this.name); }; function Fn(name) { Foo.call(this); this.name = name; } Fn.prototype = Object.create(Foo.prototype); Fn.prototype.constructor = Fn.prototype; Fn.prototype.set = function(value) { this.name = value; }; var a1 = new Fn(‘zhangsan‘); a1.age(); //zhangsan var a2 = new Fn(‘lisi‘); a2.set(‘xiaowu‘); a2.age(); //xiaowu
class写法
class Foo { constructor(name) { this.name = name; } age() { console.log(this.name); } } class Fn extends Foo { constructor(name) { super(); this.name = name; } set(value) { this.name = value; } } var a1 = new Fn(‘zhangsan‘); a1.age(); //zhangsan var a2 = new Fn(‘lisi‘); a2.set(‘xiaowu‘); a2.age(); //xiaowu
行为委托写法
var Foo = { const(name) { this.name = name; }, age() { console.log(this.name); } }; var Fn = Object.create(Foo); Fn.set = function (value) { this.name = value; }; var a1 = Object.create(Fn); a1.const(‘zhangsan‘); a1.age(); //zhangsan var a2 = Object.create(Fn); a2.set(‘xiaowu‘); a2.age(); //xiaowu
可以看到比起构造函数,行为委托是通过原型链来实现的,他值关心一件事情,对象指向的关系。
再来看一个复杂一些的例子,为dom添加样式。
function Foo(value) { this.dom = value; } Foo.prototype.div = function () { var div = document.createElement(this.dom); this._dom = document.body.appendChild(div); return this._dom; }; Foo.prototype.get = function () { return this._dom; }; function Fn(text, cssText) { Foo.call(this, ‘div‘); this.text = text; this.cssText = cssText; } Fn.prototype = Object.create(Foo.prototype); Fn.prototype.constructor = Fn.prototype; Fn.prototype.set = function () { this.div(); var div = this.get(); div.textContent = this.text; Object.keys(this.cssText).forEach((name) => { div.style.cssText += `${name}: ${this.cssText[name]}`; }); }; var a = new Fn(‘hi‘, {color: ‘red‘, "font-size": ‘16px‘}); a.set();
class写法
class Foo { constructor(value) { this.dom = value; } div() { var div = document.createElement(this.dom); this._dom = document.body.appendChild(div); return this._dom; } get() { return this._dom; } } class Fn extends Foo { constructor(text, cssText) { super(‘div‘); this.text = text; this.cssText = cssText; } set() { super.div(); var div = super.get(); div.textContent = this.text; Object.keys(this.cssText).forEach((name) => { div.style.cssText += `${name}: ${this.cssText[name]}`; }); } } var a = new Fn(‘hi‘, { color: ‘red‘, "font-size": ‘16px‘ }); a.set();
行为委托写法
var Foo = { const(value) { this.dom = value; }, div() { var div = document.createElement(this.dom); this._dom = document.body.appendChild(div); return this._dom; }, get() { return this._dom; } }; var Fn = Object.create(Foo); Fn.constructor = function (text, cssText) { this.const.call(this, ‘div‘); this.text = text; this.cssText = cssText; }; Fn.set = function () { this.div(); let div = this.get(); div.textContent = this.text; Object.keys(this.cssText).forEach((name) => { div.style.cssText += `${name}: ${this.cssText[name]}`; }); }; var a = Object.create(Fn); a.constructor(‘hi‘, { color: ‘red‘, "font-size": ‘16px‘ }); a.set();
注意点:
1.在使用行为委托时要避免标识符的重名,因为行为委托是基于原型链,不同于“类”的设计模式,可以构造函数与实例对象同时定义相同的名称的标识符。
2.两个委托对象无法互相委托,假设一个a对象关联b对象,然后b对象再关联a对象,如果两个引用了一个两个对象都不存在的属性或者方法,那么就会在原型链上形成无限循环。
以上是关于行为委托的主要内容,如果未能解决你的问题,请参考以下文章
扎实基础_设计模式_行为型_观察者模式(项目实战,使用委托注册事情,消除多重判断)
扎实基础_设计模式_行为型_观察者模式(项目实战,使用委托注册事情,消除多重判断)