首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >克隆函数实现中‘this’关键字的执行上下文

克隆函数实现中‘this’关键字的执行上下文
EN

Stack Overflow用户
提问于 2019-06-18 08:38:09
回答 1查看 37关注 0票数 0

我正在研究一个创建所提供对象的副本的函数。除了涉及this关键字的那一行之外,我基本上了解正在发生的事情。我确实理解this关键字的原始设计是为了在类定义中指向一个对象的实例,如果我们回到从C++借用的this关键字的起源。但JavaScript决定使用this关键字来提供一个额外的功能,带有到执行上下文的链接。在下面的例子中,我试图理解为什么我们要使用this关键字。如果你有任何想法,我将不胜感激。

代码语言:javascript
复制
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);
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-18 09:10:16

它用于在对特殊值进行JSON.parse/stringify的序列化/反序列化时处理嵌套对象。

在替换器/复活器函数中,this上下文是序列化器(stringify)或反序列化器(parse)正在处理的当前对象。

例如,对于下面的对象:

代码语言:javascript
复制
myObject = {
    "foo": {
        "bar": function () {}
    },
    "bar": "Different bar"
}

当它处理项myObject["foo"]["bar"]时,替换器中的this将是对带有key = "bar"value = function () {}"myObject["foo"]的引用。这很有用,因为如果没有引用,我们就不知道是在处理myObject["bar"]还是myObject["foo"]["bar"]

因此,当它被保存到数组中时,它实际上只是保存了pair = [myObject["foo"], "bar"]。稍后,当它恢复时,对于这些对中的每一个,它只需执行pair[0][pair[1]]即可恢复myObject["foo"]["bar"]

这与reviver和undefined的工作原理类似。这里的问题是reviver不能返回undefined并将值设置为undefined,所以代码片段记住哪些键是这样的,并对对象的副本进行后处理以正确设置它们。

参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#The_replacer_parameter

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56640387

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档