javascript - 克隆函数实现中“this”关键字的执行上下文
问题描述
我正在研究一个创建提供对象副本的函数。this
除了涉及关键字的行之外,我主要了解正在发生的事情。我确实明白,this
如果我们回到this
从C++
. 但是 JavaScript 决定使用this
关键字来提供一个额外的功能,携带一个指向执行上下文的链接。在下面的示例中,我试图了解我们为什么使用this
关键字。如果您有任何想法,我将不胜感激。
function clone(obj) {
const replace = {};
let idx = 0;
const undefCache = [];
const replacer = (key, value) => {
let result;
if (value === undefined) {
result = '__undefined__';
} else if (typeof value === 'symbol' || typeof value === 'function') {
const keyIdx = `__replaced__${idx}`;
idx += 1;
replace[keyIdx] = [this, key]; // I understand mostly what's happening except for the line
result = keyIdx;
} else {
result = value;
}
return result;
};
function reviver(key, value) {
let result;
if (value === '__undefined__') {
undefCache.push([this, key]);// I understand mostly what's happening except for the line
} else if (replace[value] !== undefined) {
result = replace[value][0][key];
} else {
result = value;
}
return result;
}
const json = JSON.stringify(obj, replacer);
console.log(json);
const newObject = JSON.parse(json, reviver);
undefCache.forEach(el => {
const [o, key] = el;
o[key] = undefined;
});
return newObject;
}
const source = {
a: 2,
b: '2',
c: false,
g: [
{ a: { j: undefined }, func: () => {} },
{ a: 2, b: '2', c: false, g: [{ a: { j: undefined }, func: () => {} }] }
]
};
const targetOne = clone(source);
console.log(targetOne);
解决方案
It's used to handle nested objects when doing serialization/deserialization with JSON.parse
/stringify
on special values.
Within the replacer/reviver functions, the this
context is the current object that the serializer (stringify
) or deserializer (parse
) is working on.
For example, for the object below:
myObject = {
"foo": {
"bar": function () {}
},
"bar": "Different bar"
}
When it's processing the item myObject["foo"]["bar"]
, this
inside the replacer will be a reference to myObject["foo"]
with key = "bar"
and value = function () {}"
. This is useful because without the reference, we wouldn't know whether we were processing myObject["bar"]
or myObject["foo"]["bar"]
.
Thus when it is saved into the array, it really just saved pair = [myObject["foo"], "bar"]
. Later when it's recovered, for each of these pairs, it can just do pair[0][pair[1]]
to recover myObject["foo"]["bar"]
.
This works similarly with the reviver and undefined. Here the problem is that the reviver cannot return undefined
and have the value set to undefined, so instead the code snippet remembers which keys are like this and post-processes the copy of the object to set them properly.
推荐阅读
- apache-spark - Spark Structured Streaming中从中间读取现有多级分区文件数据的问题
- json - SyntaxError:ImportJson 中的意外标记
- d3.js - D3v5 桑基图添加拖放
- python - 如何退出 True 循环并继续使用 python 中的下一段代码?
- webpack - 如何以编程方式在 Ace Editor 中添加片段?
- amazon-athena - 如何创建 parquet 分区表
- reactjs - React "interval" has always the same state
- ios - 避免由于单元格中其他按钮的高度扩展而导致按钮高度扩展
- forms - react native 中的 ref 是什么,我什么时候应该使用 ref?
- azure-data-factory-2 - Blob 到 azure sql db 加载