JavaScript中的行为委托
什么是行为委托?
简单来说就是一种设计模式,不同于传统的构造函数的“类”式设计。
在这之前先说一下原型的基本知识。
什么是原型?简单来说就是一个对象内部关联另外一个对象,本质来说就是对象与对象之间的关联;
一个对象本身没有属性或者方法会到原型对象上查找。
这里每个例子会通过构造函数,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(); //xiaowuclass写法
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对象,如果两个引用了一个两个对象都不存在的属性或者方法,那么就会在原型链上形成无限循环。
来源:https://www.cnblogs.com/boses/p/9575247.html
本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!