如何按共同特征组织数据?
How do I organize data by common traits?
我在以允许我通过数据的共同描述符或特征引用数据的方式对数据进行编目时遇到问题。我很清楚继承、特征(编程概念)和接口,但是 none 这些似乎是我问题的正确答案。
我正在 JavaScript 中编写一个程序,其中可能包含许多不同的项目或对象。假设我有一个 WoodenShortSword
的数据类型,我想表达它具有 Flammable
和 Weapon
和 OneHanded
的特征。然后,我想定义一个函数,它仅将 OneHanded
和 Weapon
的对象作为参数。或者,也许只有 Flammable
和 Wearable
,或 Flammable
和 不是 和 Weapon
.
的对象
我该怎么做?
到目前为止,我已经研究了 JavaScript 和 TypeScript 中的继承,这在技术上是可行的,但需要一堆中间 类 因为不允许多重继承。像 FlammableWeapon
或 OneHandedWeapon
。那很麻烦而且不理想。
我查看了 TypeScript 的抽象 类 和接口,但这些更多是关于共享功能,而不是描述事物。而且没有内置方法可以让我在运行时检查对象是否满足接口。
我还查看了 tcomb 库。尽管像我描述的那样的系统是可能的,但它仍然非常麻烦且容易出错。
JavaScript 对象是可扩展的,因此像 thing.Flammable=true
这样的表达式是有效的并且可以工作。
要测试对象是否具有 属性,您可以使用 thing.hasOwnProperty('property')
。这比 thing 中的 'property
更好,因为后者将包含原型链。
函数可以按如下方式工作:
function doit(object) {
if(!object.hasOwnProperty('Flammable') return;
// etc
}
这样一个对象就可以拥有多个特征,而不必费心伪造多重继承。
如果@Manngo 的方法还不是解决方案,可以考虑给予
这个答案需要 10 到 15 分钟的阅读时间。它实现了@Manngo 的方法,但侧重于
关于解决常见的组合冲突,如果涉及到组合的创建
来自有状态 mixins/traits.
的类型
根据 OP 对所需特征的描述,可以很容易地找到
基于函数的 mixin/trait 方法。从而实现细粒度 composable/reusable
每个单元都描述了一个特定的行为集
不同的(封装的)数据。
人们会实施某种 flammable
和 oneHanded
伴随的行为
通过例如一个 Weapon
基地 class.
但是从上面提到的所有内容组成一个 WoodenShortSword
并不像
正如人们第一眼看到的那样直截了当。可能有方法
来自 oneHanded
和 Weapon
需要对彼此采取行动(封装)
状态例如更新武器的 isActivated
状态
takeInLeftHand
oneHanded
的方法被调用,或者 visa verce 以防万一
武器的 deactivate
动作发生。然后很高兴得到更新
oneHanded
.
的内部 isInHand
状态
一个可靠的方法是方法修改必须依赖
在样板代码上,除非 JavaScript 在某一天本地实现
Function.prototype[around|before|after|afterReturning|afterThrowing|afterFinally]
.
作为概念证明的更长的示例代码可能看起来像这样...
function withFlammable() { // composable unit of reuse (mixin/trait/talent).
var
defineProperty = Object.defineProperty,
isInFlames = false;
defineProperty(this, 'isFlammable', {
value: true,
enumerable: true
});
defineProperty(this, 'isInFlames', {
get: function () {
return isInFlames;
},
enumerable: true
});
defineProperty(this, 'catchFire', {
value: function catchFire () {
return (isInFlames = true);
},
enumerable: true
});
defineProperty(this, 'extinguish', {
value: function extinguish () {
return (isInFlames = false);
},
enumerable: true
});
}
function withOneHanded() { // composable unit of reuse (mixin/trait/talent).
var
defineProperty = Object.defineProperty,
isInLeftHand = false,
isInRightHand = false;
function isLeftHanded() {
return (isInLeftHand && !isInRightHand);
}
function isRightHanded() {
return (isInRightHand && !isInLeftHand);
}
function isInHand() {
return (isInLeftHand || isInRightHand);
}
function putFromHand() {
return isInHand() ? (isInLeftHand = isInRightHand = false) : (void 0);
}
function takeInLeftHand() {
return !isInLeftHand ? ((isInRightHand = false) || (isInLeftHand = true)) : (void 0);
}
function takeInRightHand() {
return !isInRightHand ? ((isInLeftHand = false) || (isInRightHand = true)) : (void 0);
}
function takeInHand() {
return !isInHand() ? takeInRightHand() : (void 0);
}
function switchHand() {
return (
(isInLeftHand && ((isInLeftHand = false) || (isInRightHand = true)))
|| (isInRightHand && ((isInRightHand = false) || (isInLeftHand = true)))
);
}
defineProperty(this, 'isOneHanded', {
value: true,
enumerable: true
});
defineProperty(this, 'isLeftHanded', {
get: isLeftHanded,
enumerable: true
});
defineProperty(this, 'isRightHanded', {
get: isRightHanded,
enumerable: true
});
defineProperty(this, 'isInHand', {
get: isInHand,
enumerable: true
});
defineProperty(this, 'putFromHand', {
value: putFromHand,
enumerable: true,
writable: true
});
defineProperty(this, 'takeInLeftHand', {
value: takeInLeftHand,
enumerable: true,
writable: true
});
defineProperty(this, 'takeInRightHand', {
value: takeInRightHand,
enumerable: true,
writable: true
});
defineProperty(this, 'takeInHand', {
value: takeInHand,
enumerable: true,
writable: true
});
defineProperty(this, 'switchHand', {
value: switchHand,
enumerable: true
});
}
function withStateCoercion() { // composable unit of reuse (mixin/trait/talent).
var
defineProperty = Object.defineProperty;
defineProperty(this, 'toString', {
value: function toString () {
return JSON.stringify(this);
},
enumerable: true
});
defineProperty(this, 'valueOf', {
value: function valueOf () {
return JSON.parse(this.toString());
},
enumerable: true
});
}
class Weapon { // base type.
constructor() {
var
isActivatedState = false;
function isActivated() {
return isActivatedState;
}
function deactivate() {
return isActivatedState ? (isActivatedState = false) : (void 0);
}
function activate() {
return !isActivatedState ? (isActivatedState = true) : (void 0);
}
var
defineProperty = Object.defineProperty;
defineProperty(this, 'isActivated', {
get: isActivated,
enumerable: true
});
defineProperty(this, 'deactivate', {
value: deactivate,
enumerable: true,
writable: true
});
defineProperty(this, 'activate', {
value: activate,
enumerable: true,
writable: true
});
}
}
class WoodenShortSword extends Weapon { // ... the
constructor() { // inheritance
// part
super(); // ...
withOneHanded.call(this); // ... the
withFlammable.call(this); // composition
// base
withStateCoercion.call(this); // ...
var // ... the method modification block ...
procedWithUnmodifiedDeactivate = this.deactivate,
procedWithUnmodifiedActivate = this.activate,
procedWithUnmodifiedPutFromHand = this.putFromHand,
procedWithUnmodifiedTakeInHand = this.takeInHand,
procedWithUnmodifiedTakeInLeftHand = this.takeInLeftHand,
procedWithUnmodifiedTakeInRightHand = this.takeInRightHand;
this.deactivate = function deactivate () { // "after returning" method modification.
var
returnValue = procedWithUnmodifiedDeactivate();
if (returnValue === false) {
procedWithUnmodifiedPutFromHand();
}
return returnValue;
};
this.activate = function activate () { // "after returning" method modification.
var
returnValue = procedWithUnmodifiedActivate();
if (returnValue === true) {
procedWithUnmodifiedTakeInHand();
}
return returnValue;
};
this.putFromHand = function putFromHand () { // "after returning" method modification.
var
returnValue = procedWithUnmodifiedPutFromHand();
if (returnValue === false) {
procedWithUnmodifiedDeactivate();
}
return returnValue;
};
this.takeInHand = function takeInHand () { // "after returning" method modification.
var
returnValue = procedWithUnmodifiedTakeInHand();
if (returnValue === true) {
procedWithUnmodifiedActivate();
}
return returnValue;
};
this.takeInLeftHand = function takeInLeftHand () { // "before" method modification.
if (!this.isInHand) {
procedWithUnmodifiedActivate();
}
return procedWithUnmodifiedTakeInLeftHand();
};
this.takeInRightHand = function takeInRightHand () { // "before" method modification.
if (!this.isInHand) {
procedWithUnmodifiedActivate();
}
return procedWithUnmodifiedTakeInRightHand();
};
}
}
var
sword = new WoodenShortSword;
console.log('sword : ', sword);
console.log('(sword + "") : ', (sword + ""));
console.log('sword.valueOf() : ', sword.valueOf());
console.log('\n');
console.log('sword.isFlammable : ', sword.isFlammable);
console.log('sword.isInFlames : ', sword.isInFlames);
console.log('\n');
console.log('sword.isOneHanded : ', sword.isOneHanded);
console.log('sword.isLeftHanded : ', sword.isLeftHanded);
console.log('sword.isRightHanded : ', sword.isRightHanded);
console.log('sword.isInHand : ', sword.isInHand);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.deactivate : ', sword.deactivate);
console.log('sword.activate : ', sword.activate);
console.log('\n');
console.log('sword.deactivate() : ', sword.deactivate());
console.log('sword.activate() : ', sword.activate());
console.log('sword.activate() : ', sword.activate());
console.log('\n');
console.log('sword.isFlammable : ', sword.isFlammable);
console.log('sword.isInFlames : ', sword.isInFlames);
console.log('\n');
console.log('sword.isOneHanded : ', sword.isOneHanded);
console.log('sword.isLeftHanded : ', sword.isLeftHanded);
console.log('sword.isRightHanded : ', sword.isRightHanded);
console.log('sword.isInHand : ', sword.isInHand);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.switchHand() : ', sword.switchHand());
console.log('\n');
console.log('sword.isLeftHanded : ', sword.isLeftHanded);
console.log('sword.isRightHanded : ', sword.isRightHanded);
console.log('sword.isInHand : ', sword.isInHand);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.takeInRightHand() : ', sword.takeInRightHand());
console.log('\n');
console.log('sword.isLeftHanded : ', sword.isLeftHanded);
console.log('sword.isRightHanded : ', sword.isRightHanded);
console.log('sword.isInHand : ', sword.isInHand);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.putFromHand() : ', sword.putFromHand());
console.log('\n');
console.log('sword.isLeftHanded : ', sword.isLeftHanded);
console.log('sword.isRightHanded : ', sword.isRightHanded);
console.log('sword.isInHand : ', sword.isInHand);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.takeInLeftHand() : ', sword.takeInLeftHand());
console.log('\n');
console.log('sword.isLeftHanded : ', sword.isLeftHanded);
console.log('sword.isRightHanded : ', sword.isRightHanded);
console.log('sword.isInHand : ', sword.isInHand);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.deactivate() : ', sword.deactivate());
console.log('\n');
console.log('sword.isLeftHanded : ', sword.isLeftHanded);
console.log('sword.isRightHanded : ', sword.isRightHanded);
console.log('sword.isInHand : ', sword.isInHand);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.activate() : ', sword.activate());
console.log('\n');
console.log('sword.isLeftHanded : ', sword.isLeftHanded);
console.log('sword.isRightHanded : ', sword.isRightHanded);
console.log('sword.isInHand : ', sword.isInHand);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.switchHand() : ', sword.switchHand());
console.log('\n');
console.log('sword.isFlammable : ', sword.isFlammable);
console.log('sword.isInFlames : ', sword.isInFlames);
console.log('\n');
console.log('sword.isLeftHanded : ', sword.isLeftHanded);
console.log('sword.isRightHanded : ', sword.isRightHanded);
console.log('sword.isInHand : ', sword.isInHand);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.catchFire() : ', sword.catchFire());
console.log('\n');
console.log('sword.isFlammable : ', sword.isFlammable);
console.log('sword.isInFlames : ', sword.isInFlames);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.extinguish() : ', sword.extinguish());
console.log('\n');
console.log('sword.isFlammable : ', sword.isFlammable);
console.log('sword.isInFlames : ', sword.isInFlames);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.putFromHand() : ', sword.putFromHand());
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
.as-console-wrapper { max-height: 100%!important; top: 0; }
我在以允许我通过数据的共同描述符或特征引用数据的方式对数据进行编目时遇到问题。我很清楚继承、特征(编程概念)和接口,但是 none 这些似乎是我问题的正确答案。
我正在 JavaScript 中编写一个程序,其中可能包含许多不同的项目或对象。假设我有一个 WoodenShortSword
的数据类型,我想表达它具有 Flammable
和 Weapon
和 OneHanded
的特征。然后,我想定义一个函数,它仅将 OneHanded
和 Weapon
的对象作为参数。或者,也许只有 Flammable
和 Wearable
,或 Flammable
和 不是 和 Weapon
.
我该怎么做?
到目前为止,我已经研究了 JavaScript 和 TypeScript 中的继承,这在技术上是可行的,但需要一堆中间 类 因为不允许多重继承。像 FlammableWeapon
或 OneHandedWeapon
。那很麻烦而且不理想。
我查看了 TypeScript 的抽象 类 和接口,但这些更多是关于共享功能,而不是描述事物。而且没有内置方法可以让我在运行时检查对象是否满足接口。
我还查看了 tcomb 库。尽管像我描述的那样的系统是可能的,但它仍然非常麻烦且容易出错。
JavaScript 对象是可扩展的,因此像 thing.Flammable=true
这样的表达式是有效的并且可以工作。
要测试对象是否具有 属性,您可以使用 thing.hasOwnProperty('property')
。这比 thing 中的 'property
更好,因为后者将包含原型链。
函数可以按如下方式工作:
function doit(object) {
if(!object.hasOwnProperty('Flammable') return;
// etc
}
这样一个对象就可以拥有多个特征,而不必费心伪造多重继承。
如果@Manngo 的方法还不是解决方案,可以考虑给予 这个答案需要 10 到 15 分钟的阅读时间。它实现了@Manngo 的方法,但侧重于 关于解决常见的组合冲突,如果涉及到组合的创建 来自有状态 mixins/traits.
的类型根据 OP 对所需特征的描述,可以很容易地找到 基于函数的 mixin/trait 方法。从而实现细粒度 composable/reusable 每个单元都描述了一个特定的行为集 不同的(封装的)数据。
人们会实施某种 flammable
和 oneHanded
伴随的行为
通过例如一个 Weapon
基地 class.
但是从上面提到的所有内容组成一个 WoodenShortSword
并不像
正如人们第一眼看到的那样直截了当。可能有方法
来自 oneHanded
和 Weapon
需要对彼此采取行动(封装)
状态例如更新武器的 isActivated
状态
takeInLeftHand
oneHanded
的方法被调用,或者 visa verce 以防万一
武器的 deactivate
动作发生。然后很高兴得到更新
oneHanded
.
isInHand
状态
一个可靠的方法是方法修改必须依赖
在样板代码上,除非 JavaScript 在某一天本地实现
Function.prototype[around|before|after|afterReturning|afterThrowing|afterFinally]
.
作为概念证明的更长的示例代码可能看起来像这样...
function withFlammable() { // composable unit of reuse (mixin/trait/talent).
var
defineProperty = Object.defineProperty,
isInFlames = false;
defineProperty(this, 'isFlammable', {
value: true,
enumerable: true
});
defineProperty(this, 'isInFlames', {
get: function () {
return isInFlames;
},
enumerable: true
});
defineProperty(this, 'catchFire', {
value: function catchFire () {
return (isInFlames = true);
},
enumerable: true
});
defineProperty(this, 'extinguish', {
value: function extinguish () {
return (isInFlames = false);
},
enumerable: true
});
}
function withOneHanded() { // composable unit of reuse (mixin/trait/talent).
var
defineProperty = Object.defineProperty,
isInLeftHand = false,
isInRightHand = false;
function isLeftHanded() {
return (isInLeftHand && !isInRightHand);
}
function isRightHanded() {
return (isInRightHand && !isInLeftHand);
}
function isInHand() {
return (isInLeftHand || isInRightHand);
}
function putFromHand() {
return isInHand() ? (isInLeftHand = isInRightHand = false) : (void 0);
}
function takeInLeftHand() {
return !isInLeftHand ? ((isInRightHand = false) || (isInLeftHand = true)) : (void 0);
}
function takeInRightHand() {
return !isInRightHand ? ((isInLeftHand = false) || (isInRightHand = true)) : (void 0);
}
function takeInHand() {
return !isInHand() ? takeInRightHand() : (void 0);
}
function switchHand() {
return (
(isInLeftHand && ((isInLeftHand = false) || (isInRightHand = true)))
|| (isInRightHand && ((isInRightHand = false) || (isInLeftHand = true)))
);
}
defineProperty(this, 'isOneHanded', {
value: true,
enumerable: true
});
defineProperty(this, 'isLeftHanded', {
get: isLeftHanded,
enumerable: true
});
defineProperty(this, 'isRightHanded', {
get: isRightHanded,
enumerable: true
});
defineProperty(this, 'isInHand', {
get: isInHand,
enumerable: true
});
defineProperty(this, 'putFromHand', {
value: putFromHand,
enumerable: true,
writable: true
});
defineProperty(this, 'takeInLeftHand', {
value: takeInLeftHand,
enumerable: true,
writable: true
});
defineProperty(this, 'takeInRightHand', {
value: takeInRightHand,
enumerable: true,
writable: true
});
defineProperty(this, 'takeInHand', {
value: takeInHand,
enumerable: true,
writable: true
});
defineProperty(this, 'switchHand', {
value: switchHand,
enumerable: true
});
}
function withStateCoercion() { // composable unit of reuse (mixin/trait/talent).
var
defineProperty = Object.defineProperty;
defineProperty(this, 'toString', {
value: function toString () {
return JSON.stringify(this);
},
enumerable: true
});
defineProperty(this, 'valueOf', {
value: function valueOf () {
return JSON.parse(this.toString());
},
enumerable: true
});
}
class Weapon { // base type.
constructor() {
var
isActivatedState = false;
function isActivated() {
return isActivatedState;
}
function deactivate() {
return isActivatedState ? (isActivatedState = false) : (void 0);
}
function activate() {
return !isActivatedState ? (isActivatedState = true) : (void 0);
}
var
defineProperty = Object.defineProperty;
defineProperty(this, 'isActivated', {
get: isActivated,
enumerable: true
});
defineProperty(this, 'deactivate', {
value: deactivate,
enumerable: true,
writable: true
});
defineProperty(this, 'activate', {
value: activate,
enumerable: true,
writable: true
});
}
}
class WoodenShortSword extends Weapon { // ... the
constructor() { // inheritance
// part
super(); // ...
withOneHanded.call(this); // ... the
withFlammable.call(this); // composition
// base
withStateCoercion.call(this); // ...
var // ... the method modification block ...
procedWithUnmodifiedDeactivate = this.deactivate,
procedWithUnmodifiedActivate = this.activate,
procedWithUnmodifiedPutFromHand = this.putFromHand,
procedWithUnmodifiedTakeInHand = this.takeInHand,
procedWithUnmodifiedTakeInLeftHand = this.takeInLeftHand,
procedWithUnmodifiedTakeInRightHand = this.takeInRightHand;
this.deactivate = function deactivate () { // "after returning" method modification.
var
returnValue = procedWithUnmodifiedDeactivate();
if (returnValue === false) {
procedWithUnmodifiedPutFromHand();
}
return returnValue;
};
this.activate = function activate () { // "after returning" method modification.
var
returnValue = procedWithUnmodifiedActivate();
if (returnValue === true) {
procedWithUnmodifiedTakeInHand();
}
return returnValue;
};
this.putFromHand = function putFromHand () { // "after returning" method modification.
var
returnValue = procedWithUnmodifiedPutFromHand();
if (returnValue === false) {
procedWithUnmodifiedDeactivate();
}
return returnValue;
};
this.takeInHand = function takeInHand () { // "after returning" method modification.
var
returnValue = procedWithUnmodifiedTakeInHand();
if (returnValue === true) {
procedWithUnmodifiedActivate();
}
return returnValue;
};
this.takeInLeftHand = function takeInLeftHand () { // "before" method modification.
if (!this.isInHand) {
procedWithUnmodifiedActivate();
}
return procedWithUnmodifiedTakeInLeftHand();
};
this.takeInRightHand = function takeInRightHand () { // "before" method modification.
if (!this.isInHand) {
procedWithUnmodifiedActivate();
}
return procedWithUnmodifiedTakeInRightHand();
};
}
}
var
sword = new WoodenShortSword;
console.log('sword : ', sword);
console.log('(sword + "") : ', (sword + ""));
console.log('sword.valueOf() : ', sword.valueOf());
console.log('\n');
console.log('sword.isFlammable : ', sword.isFlammable);
console.log('sword.isInFlames : ', sword.isInFlames);
console.log('\n');
console.log('sword.isOneHanded : ', sword.isOneHanded);
console.log('sword.isLeftHanded : ', sword.isLeftHanded);
console.log('sword.isRightHanded : ', sword.isRightHanded);
console.log('sword.isInHand : ', sword.isInHand);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.deactivate : ', sword.deactivate);
console.log('sword.activate : ', sword.activate);
console.log('\n');
console.log('sword.deactivate() : ', sword.deactivate());
console.log('sword.activate() : ', sword.activate());
console.log('sword.activate() : ', sword.activate());
console.log('\n');
console.log('sword.isFlammable : ', sword.isFlammable);
console.log('sword.isInFlames : ', sword.isInFlames);
console.log('\n');
console.log('sword.isOneHanded : ', sword.isOneHanded);
console.log('sword.isLeftHanded : ', sword.isLeftHanded);
console.log('sword.isRightHanded : ', sword.isRightHanded);
console.log('sword.isInHand : ', sword.isInHand);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.switchHand() : ', sword.switchHand());
console.log('\n');
console.log('sword.isLeftHanded : ', sword.isLeftHanded);
console.log('sword.isRightHanded : ', sword.isRightHanded);
console.log('sword.isInHand : ', sword.isInHand);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.takeInRightHand() : ', sword.takeInRightHand());
console.log('\n');
console.log('sword.isLeftHanded : ', sword.isLeftHanded);
console.log('sword.isRightHanded : ', sword.isRightHanded);
console.log('sword.isInHand : ', sword.isInHand);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.putFromHand() : ', sword.putFromHand());
console.log('\n');
console.log('sword.isLeftHanded : ', sword.isLeftHanded);
console.log('sword.isRightHanded : ', sword.isRightHanded);
console.log('sword.isInHand : ', sword.isInHand);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.takeInLeftHand() : ', sword.takeInLeftHand());
console.log('\n');
console.log('sword.isLeftHanded : ', sword.isLeftHanded);
console.log('sword.isRightHanded : ', sword.isRightHanded);
console.log('sword.isInHand : ', sword.isInHand);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.deactivate() : ', sword.deactivate());
console.log('\n');
console.log('sword.isLeftHanded : ', sword.isLeftHanded);
console.log('sword.isRightHanded : ', sword.isRightHanded);
console.log('sword.isInHand : ', sword.isInHand);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.activate() : ', sword.activate());
console.log('\n');
console.log('sword.isLeftHanded : ', sword.isLeftHanded);
console.log('sword.isRightHanded : ', sword.isRightHanded);
console.log('sword.isInHand : ', sword.isInHand);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.switchHand() : ', sword.switchHand());
console.log('\n');
console.log('sword.isFlammable : ', sword.isFlammable);
console.log('sword.isInFlames : ', sword.isInFlames);
console.log('\n');
console.log('sword.isLeftHanded : ', sword.isLeftHanded);
console.log('sword.isRightHanded : ', sword.isRightHanded);
console.log('sword.isInHand : ', sword.isInHand);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.catchFire() : ', sword.catchFire());
console.log('\n');
console.log('sword.isFlammable : ', sword.isFlammable);
console.log('sword.isInFlames : ', sword.isInFlames);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.extinguish() : ', sword.extinguish());
console.log('\n');
console.log('sword.isFlammable : ', sword.isFlammable);
console.log('sword.isInFlames : ', sword.isInFlames);
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
console.log('sword.putFromHand() : ', sword.putFromHand());
console.log('\n');
console.log('sword.isActivated : ', sword.isActivated);
console.log('\n');
.as-console-wrapper { max-height: 100%!important; top: 0; }