Javascript 克隆函数实现中“this”关键字的执行上下文
我正在研究一个函数,该函数创建所提供对象的副本。除了涉及这个关键字的那一行之外,我基本上了解正在发生的事情。我明白,这个关键字的原始设计是指指向类定义中的对象实例,如果我们回到从C++借用的这个关键字的起源。但是JavaScript决定使用这个关键字来提供一个额外的特性,即携带一个指向执行上下文的链接。在下面的例子中,我试图理解为什么我们要使用这个关键字。如果你有任何想法,我将非常感激Javascript 克隆函数实现中“this”关键字的执行上下文,javascript,Javascript,我正在研究一个函数,该函数创建所提供对象的副本。除了涉及这个关键字的那一行之外,我基本上了解正在发生的事情。我明白,这个关键字的原始设计是指指向类定义中的对象实例,如果我们回到从C++借用的这个关键字的起源。但是JavaScript决定使用这个关键字来提供一个额外的特性,即携带一个指向执行上下文的链接。在下面的例子中,我试图理解为什么我们要使用这个关键字。如果你有任何想法,我将非常感激 function clone(obj) { const replace = {}; let idx =
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);
在对特殊值使用JSON.parse/stringify进行序列化/反序列化时,它用于处理嵌套对象 在replace/reviver函数中,此上下文是序列化程序stringify或反序列化程序解析正在处理的当前对象 例如,对于以下对象:
myObject = {
"foo": {
"bar": function () {}
},
"bar": "Different bar"
}
当它处理项目myObject[foo][bar]时,替换程序中的这个将是对myObject[foo]的引用,key=bar,value=function{}。这很有用,因为如果没有引用,我们就不知道是在处理myObject[bar]还是myObject[foo][bar]
因此,当它被保存到数组中时,它实际上只是保存了pair=[myObject[foo],bar]。稍后恢复时,对于这些对中的每一对,只需执行对[0][对[1]]即可恢复myObject[foo][bar]
这同样适用于复活者和未定义者。这里的问题是,恢复程序不能返回undefined并将值设置为undefined,因此代码段会记住哪些键是这样的,并对对象的副本进行后期处理以正确设置它们
Ref:查看调用方API/契约,了解这是什么设置--。。然后调用[reviver],对象包含如下处理的属性,属性名称为字符串,属性值为参数。。。在这种情况下,考虑到它与表达函数RealValueObjt属性、键、值……的方式没有什么不同,除了通过此方式访问ObjutWess属性。