假设我有一个方法可以根据当前值更改值。我在这里就让它变得非常简单:
changeValue(){
if(!this.value){
this.value = 'value1'
}
else if(this.value === 'value1'){
this.value = 'value2'
}
else if(this.value === 'value2'){
this.value = 'value3'
}
},
然后我有另一种方法,如果当前值为 2 或 3,则更改为第四个值
changeValues(){
if(this.value === 'value2' || this.value === 'value3'){
this.value = 'valueX'
}
},
现在我想添加一个点击事件,将 valueX 的值更改回以前的值,但我无法在代码中指定它,因为以前的值可能是 value2 或 value3。
有没有办法查看变量“历史记录”,检查以前的内容,然后将其设置回原来的状态?
changeBack(){
// if last value was value2 change back to value2
// if last value was value3 then change back to value3
}
您可以使用数组来跟踪值的历史记录。
示例:
class YourClass {
constructor() {
this.value = null;
this.valueHistory = [];
}
changeValue() {
if (!this.value) {
this.value = 'value1';
} else if (this.value === 'value1') {
this.value = 'value2';
} else if (this.value === 'value2') {
this.value = 'value3';
}
// Save the current value to history
this.valueHistory.push(this.value);
}
changeValues() {
if (this.value === 'value2' || this.value === 'value3') {
this.value = 'valueX';
}
}
changeBack() {
// Pop the last value from history and set it as the current value
if (this.valueHistory.length > 0) {
this.value = this.valueHistory.pop();
}
}
}
valueHistory
是一个跟踪值历史记录的数组。 changeBack 方法从历史数组中弹出最后一个值并将其设置为当前值。
let valueHistory = [];
function changeValue(newValue) {
valueHistory.push(this.value);
this.value = newValue;
}
function changeBack() {
if (valueHistory.length > 0) {
this.value = valueHistory.pop();
}
}
changeValue('hasanraza');
console.log(this.value);
你的问题被标记为 vue.js,所以我在 vue 中回答
您可以使用 vue 观察程序并创建一个列表,然后通过索引或带有所有更改的键:值对的对象来选择它们。
data() {
return {
val: '',
listOfValues: [],
}
},
watch: {
val(newVal, oldVal) {
this.listOfValues.push(newVal)
// or with if statement if you want to check
if (...) {
}
}
},
WeakMap
。这样的注册表的键专门是对象的引用,其中后者想要存储每个对象条目的值历史记录。因此,注册表的每个值都需要是一个 Map
实例,其中基于映射字符串的键是对象条目的属性名称,值是 Set
实例。后者用作对象的某个条目(键值对)的所有最近唯一值的历史存储。
get
/set
功能来实现,该功能根据要设置的值确实跟踪每个新的、唯一设置的值。
代码必须附带两个辅助函数,例如
getPreviousOfValueHistory
和 getNextOfValueHistory
,其中每个函数根据传递的参数 target
、key
和 value
确实返回 target
对象特定的 key
指示的属性,或者是之前的值,或者是传递的下一个值value
参数。
如果
value
未出现在 target
/key
指示属性的值历史记录中,则将返回符号值 Symbol('no history value found')
。
如果
value
与第一个或最后一个唯一历史值匹配,则返回该值本身。
示例代码...
const noHistoryValueFound = Symbol('no history value found');
const valueHistoryRegistry = new WeakMap;
const getPreviousOfValueHistory = (target, key, value) => {
let result = noHistoryValueFound;
const valueHistory =
valueHistoryRegistry?.get(target)?.get(key);
if (valueHistory) {
const valueList = [...valueHistory];
let valueIdx = valueList.indexOf(value);
if (valueIdx >= 0) {
result = (--valueIdx in valueList)
? valueList.at(valueIdx)
: value;
}
}
return result;
}
const getNextOfValueHistory = (target, key, value) => {
let result = noHistoryValueFound;
const valueHistory =
valueHistoryRegistry?.get(target)?.get(key);
if (valueHistory) {
const valueList = [...valueHistory];
let valueIdx = valueList.indexOf(value);
if (valueIdx >= 0) {
result = (++valueIdx in valueList)
? valueList.at(valueIdx)
: value;
}
}
return result;
}
const logUniqueValueHistory = (target, key, value) => {
if (valueHistoryRegistry.has(target)) {
const valueRegistry = valueHistoryRegistry.get(target);
if (valueRegistry.has(key)) {
const valueHistory = valueRegistry.get(key);
if (!valueHistory.has(value)) {
valueHistory
.add(value);
}
} else {
valueRegistry
.set(key, new Set([value]));
}
} else {
valueHistoryRegistry
.set(target, new Map([[key, new Set([value])]]));
}
}
const getSnapshotOfWritableOwnProperties = (value) => {
const source = Object(value);
return Object
.entries(
Object.getOwnPropertyDescriptors(source)
)
.concat(
Object
.getOwnPropertySymbols(source)
.map(symbol => [symbol, Object.getOwnPropertyDescriptor(source, symbol)])
)
.filter(([_, descriptor]) =>
!!descriptor.writable && Object.hasOwn(descriptor, 'value')
)
.reduce((snapshot, [key, { value }]) => {
snapshot[key] = value;
return snapshot;
}, {});
}
function withContextuallyBoundUniqueValueHistoryLogging(key, value) {
const { context, state } = this;
Reflect.defineProperty(context, key, {
get: () => Reflect.get(state, key),
set: value => {
logUniqueValueHistory(context, key, value);
return Reflect.set(state, key, value);
},
});
}
function withOwnUniqueValueHistory() {
const state = getSnapshotOfWritableOwnProperties(this);
Object
.entries(state)
.concat(
Object
.getOwnPropertySymbols(state)
.map(symbol => [symbol, Reflect.get(state, symbol)])
)
.forEach(([key, value]) => {
withContextuallyBoundUniqueValueHistoryLogging
.call({ context: this, state }, key, value);
// - force 1st history-value entry
// for every instance property.
this[key] = value;
});
}
class KeyValueStorageWithUniqueValueHistory {
constructor(initialState= {}) {
Object
.assign(this, Object(initialState));
withOwnUniqueValueHistory.call(this);
}
previousValueOf(...args) {
const key = args.at(0);
const value = ('1' in args) ? args.at(1) : this[key];
return getPreviousOfValueHistory(this, key, value);
}
nextValueOf(...args) {
const key = args.at(0);
const value = ('1' in args) ? args.at(1) : this[key];
return getNextOfValueHistory(this, key, value);
}
}
const fooBarSymbol = Symbol('fooBar');
const storage = new KeyValueStorageWithUniqueValueHistory({
quickBrownFox: 'the',
[fooBarSymbol]: 'foo',
});
console.log(`const storage = new KeyValueStorageWithUniqueValueHistory({
quickBrownFox: 'the',
fooBarBazBiz: 'foo',
})`);
console.log('storage.quickBrownFox ...', storage.quickBrownFox);
console.log('\n');
console.log("storage.quickBrownFox = 'quick';");
storage.quickBrownFox = 'quick';
console.log('storage.quickBrownFox ...', storage.quickBrownFox);
console.log('\n');
console.log("storage.quickBrownFox = 'brown';");
storage.quickBrownFox = 'brown';
console.log('storage.quickBrownFox ...', storage.quickBrownFox);
console.log('\n');
console.log("storage.quickBrownFox = 'fox';");
storage.quickBrownFox = 'fox';
console.log('storage.quickBrownFox ...', storage.quickBrownFox);
console.log('\n');
console.log("storage.quickBrownFox = 'jumps';");
storage.quickBrownFox = 'jumps';
console.log('storage.quickBrownFox ...', storage.quickBrownFox);
console.log('----- ----- ----- ----- -----');
console.log("storage.quickBrownFox = 'brown';");
storage.quickBrownFox = 'brown';
console.log('storage.quickBrownFox ...', storage.quickBrownFox);
console.log('\n');
console.log(
"storage.previousValueOf('quickBrownFox') ...",
storage.previousValueOf('quickBrownFox'),
);
console.log(
"storage.nextValueOf('quickBrownFox') ...",
storage.nextValueOf('quickBrownFox'),
);
console.log('\n');
console.log(
"storage.previousValueOf('quickBrownFox', 'quick') ...",
storage.previousValueOf('quickBrownFox', 'quick'),
);
console.log(
"storage.previousValueOf('quickBrownFox', 'jumps') ...",
storage.previousValueOf('quickBrownFox', 'jumps'),
);
console.log('\n');
console.log(
"storage.nextValueOf('quickBrownFox', 'the') ...",
storage.nextValueOf('quickBrownFox', 'the'),
);
console.log(
"storage.nextValueOf('quickBrownFox', 'fox') ...",
storage.nextValueOf('quickBrownFox', 'fox'),
);
console.log('----- ----- ----- ----- -----');
console.log('storage[fooBarSymbol] ...',storage[fooBarSymbol]);
console.log(
"storage.previousValueOf(fooBarSymbol) ...",
storage.previousValueOf(fooBarSymbol),
);
console.log(
"storage.nextValueOf(fooBarSymbol) ...",
storage.nextValueOf(fooBarSymbol),
);
console.log('\n');
console.log(
"storage.nextValueOf(fooBarSymbol, 'bar') ...",
String(storage.nextValueOf(fooBarSymbol, 'bar')),
);
console.log('----- ----- ----- ----- -----');
console.log("storage[fooBarSymbol] = 'bar';");
storage[fooBarSymbol] = 'bar';
console.log('storage[fooBarSymbol] ...', storage[fooBarSymbol]);
console.log('\n');
console.log("storage[fooBarSymbol] = 'baz';");
storage[fooBarSymbol] = 'baz';
console.log('storage[fooBarSymbol] ...', storage[fooBarSymbol]);
console.log('\n');
console.log("storage[fooBarSymbol] = 'biz';");
storage[fooBarSymbol] = 'biz';
console.log('storage[fooBarSymbol] ...', storage[fooBarSymbol]);
console.log('----- ----- ----- ----- -----');
console.log("storage[fooBarSymbol] = 'bar';");
storage[fooBarSymbol] = 'bar';
console.log('storage[fooBarSymbol] ...', storage[fooBarSymbol]);
console.log('\n');
console.log(
"storage.previousValueOf(fooBarSymbol) ...",
storage.previousValueOf(fooBarSymbol),
);
console.log(
"storage.nextValueOf(fooBarSymbol) ...",
storage.nextValueOf(fooBarSymbol),
);
console.log('\n');
console.log(
"storage.previousValueOf(fooBarSymbol, 'biz') ...",
storage.previousValueOf(fooBarSymbol, 'biz'),
);
console.log(
"storage.nextValueOf(fooBarSymbol, 'baz') ...",
storage.nextValueOf(fooBarSymbol, 'baz'),
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
考虑到上述示例代码提供的所有内容,OP 现在可以轻松地将具有挑战性的
changeValues
函数从 ...
changeValues () {
if (this.value === 'value2' || this.value === 'value3') {
this.value = 'valueX';
}
}
...到...
changeBack () {
if (this.value === 'value2' || this.value === 'value3') {
this.value
= getPreviousOfValueHistory(this, 'value', this.value);
}
}
同样,堆栈片段的示例代码确实提供了
getPreviousOfValueHistory
的实现及其用法示例。