背景资料
这也是程序设计模式系列第八节,学习培训是指patterns.dev里程序设计模式中混合模式具体内容,因为是材料是英语版,所以我的学习心得就含有汉语翻译的特性,但是并不是汉语翻译,纪录的是自己学习的过程与理解。
第一节:分布式系统所造成的数据分析艰难?看着我单例设计模式一招制敌
第二节:JS和热巴一样有专门替身演员?没听说过的赶紧来补补习...
第三节:仍在逐层传送props?来学习非常实用的经销商方式吧
第四节:都懂JavaScript原形,但程序设计模式中的原型模式你能使用吗?
第五节:React Hooks时期,如何完成主视图与逻辑性分离出来呢?
第六节:现在是时候取出高档的技术了————观察者模式
第七节:前面性能调优实战篇——动态加载控制模块基本补遗
写在前面
前边大家学习原型模式时,学习培训了一些关于原形的基础知识,我们都知道根据原形是能够给对象添加属性和方法。并且通过Object.assign方式或是proto特性添加属性,其实就是今天给大家说的混合模式。
简约释意
在不能使用传承的情形下给Object目标或是class类加上函数公式。
基本完成方法就是使用Object.assign方式给总体目标类原型(prototype)上添加属性, 随后创好的对象都能够浏览添加的函数公式。
class Dog {
constructor(name) {
this.name = name;
}
}
const dogFunctionality = {
bark: () => console.log("Woof!"),
wagTail: () => console.log("Wagging my tail!"),
play: () => console.log("Playing!")
};
Object.assign(Dog.prototype, dogFunctionality);
根据给Dog这一类原型加上方式,如今我们能直接启用新增加的方式了:
const pet1 = new Dog("Daisy");
pet1.name; // Daisy
pet1.bark(); // Woof!
pet1.play(); // Playing!
被混合在一起Object中间可以用传承
混合模式容许给Class和Object不能使用传承加上属性和方法,与此同时被混和的Object之间有能够应用传承的。
看看下面的事例:
const animalFunctionality = {
walk: () => console.log("Walking!"),
sleep: () => console.log("Sleeping!")
};
const dogFunctionality = {
bark: () => console.log("Woof!"),
wagTail: () => console.log("Wagging my tail!"),
play: () => console.log("Playing!"),
walk() {
super.walk();
},
sleep() {
super.sleep();
}
};
Object.assign(dogFunctionality, animalFunctionality);
Object.assign(Dog.prototype, dogFunctionality);
在后面的例子中,我们先应用Object.assign给dogFunctionality加了小动物animalFunctionality的函数公式,接着又把dogFunctionality中的函数公式加上给Dog这一类原形。
这个案例能够换个原型的书写Proto来达到,一个意思:
class Dog {
constructor(name) {
this.name = name;
}
}
const animalFunctionality = {
fly: ()=>console.log("fly"),
walk: () => console.log("Walking!"),
sleep: () => console.log("Sleeping!")
};
const dogFunctionality = {
__proto__: animalFunctionality,
bark: () => console.log("Woof!"),
wagTail: () => console.log("Wagging my tail!"),
play: () => console.log("Playing!"),
walk() {
super.walk();
},
sleep() {
super.sleep();
}
};
Object.assign(Dog.prototype, dogFunctionality);
const pet1 = new Dog("Daisy");
console.log(pet1.name); // Daisy
pet1.bark(); // Woof!
pet1.play(); // Playing!
pet1.walk(); // Walking!
pet1.sleep(); // Sleeping!
// 调节
pet1.fly(); // Error, pet1.fly is not a function
console.log(pet1.__proto__); //{bark...wagTail...play...walk...sleep}
console.log(Dog.prototype); //{bark...wagTail...play...walk...sleep}
console.log(dogFunctionality.__proto__); //{fly...walk...sleep}
console.log(animalFunctionality.__proto__); //{}
线上实例
需注意,dogFunctionality 原型的方式fly,Dog类中没法启用;
给Dog加上原型,并没有把所加上原型的原形中的方式给加上上;
Dog类浏览原形用prototype, Dog的实例对象或其它随意目标经过**_proto_**浏览原形;
只支持函数公式,不兼容别的特性;
经典案例
电脑浏览器window目标
在实际的运用中一个较为明显混合模式是电脑浏览器页面中的window目标。window对象许多特性完成自WindowOrWorkerGlobalScope
和WindowEventHandler
的组合,最后我们才能进行例如setTimeout
和setInterval
,indexedDB
, 和isSecureContext
这种特性。
由于混合模式下,只有完成给Object对象添加函数公式特性,而无法直接启用例如WindowOrWorkerGlobalScope 这种目标。
window.indexedDB.open("toDoList");
window.addEventListener("beforeunload", event => {
event.preventDefault();
event.returnValue = "";
});
window.onbeforeunload = function() {
console.log("Unloading!");
};
// 能够启用混匀的特性
console.log(
"From WindowEventHandlers mixin: onbeforeunload",
window.onbeforeunload
);
console.log(
"From WindowOrWorkerGlobalScope mixin: isSecureContext",
window.isSecureContext
);
// 能够启用被混合在一起目标
console.log(
"WindowEventHandlers itself is undefined",
window.WindowEventHandlers
);
console.log(
"WindowOrWorkerGlobalScope itself is undefined",
window.WindowOrWorkerGlobalScope
);
ES6以前的React
在React引进ES6以前,频繁使用混合模式给React部件加上函数公式。
React团队并不建议应用混合模式,由于这时候给部件产生不必要复杂性,而且无法日常维护重复使用;反而是建议使用高阶函数,其实现在大多数被hooks方法替代了。
汇总
混合模式容许大家在不能使用传承的情形下,用给目标原形引入函数公式的形式,进而真正实现地对对象添加函数公式。可是改动目标原形通常并并不是好的方式,因为他们可能会致使原形环境污染和一定程度的函数公式追溯错乱。
打开AdminJS成长之路!这个是我参加「AdminJS日新的目标 · 2 月更文考验」第 1 天,查看更多活动规则