【问题标题】:Unable to access object variable from bound function, or internal method from unbound function无法从绑定函数访问对象变量,或从未绑定函数访问内部方法
【发布时间】:2018-12-31 12:37:18
【问题描述】:

仅供参考,我正在尝试遵循Abstract Encoding 规范。本质上,我想创建一个“函数变量”let foo = codec.encode,其中encode() 调用codec 中的另一个函数,我可以访问foo.bytes。看来我可以访问bytes 的值但不能访问内部函数this.encodingLength(),或者创建一个绑定函数变量并发生完全相反的情况。仅当我将函数 encode() 分配给变量时才会出现此问题。我在某处读到bind() 创建了一个包装函数(无法访问bytes,并且如果没有正确的上下文,对象函数也无法访问其他对象函数。是否有可能两个世界?

示例代码:

const codec = {
  encode: function encode () {
    encode.bytes = 2
    this.encodingLength()
  },
  encodingLength: function encodingLength () { }
}

let foo = codec.encode
let bar = codec.encode.bind(codec)

> foo()
TypeError: this.encodingLength is not a function
    at encode (repl:4:6)
> foo.bytes
2

> bar()
undefined
> bar.bytes
undefined

也使用this.encode.bytes 似乎没什么区别

const codec = {
  encode () {
    this.encode.bytes = 2
    this.encodingLength()
  },
  encodingLength () { }
}

【问题讨论】:

  • 您是否希望bytes 对于encode 的每次调用都(可能)不同?
  • 是的(应该是),尽管出于演示目的,我只是将其分配给2
  • 仅供参考,为调用返回值指定一个全局变量是一件可怕的事情。
  • 您能详细说明一下吗?
  • 您链接的“抽象编码”规范说“编码后encoding.encode.bytes 应设置为用于编码对象的字节数。”。 encoding.encode.bytes 本质上是一个全局变量,除非他们假设每个编码都被实例化为具有非共享方法的一次性对象。并且使用全局变量来传递返回值是一个可怕的想法 - 这也会导致您的问题。

标签: javascript node.js javascript-objects ecmascript-5


【解决方案1】:

这对你有用吗?

// define encodingLength function here
function encodingLength(object) {
  // determine encoding length of obj here
  return 5; // dummy value
}

const codec = {
  encode: function encode(object, buffer, offset) {
    // encode object here
    // capture `encodingLength` in a closure
    encode.bytes = encodingLength(object); // dummy value
    return []; // dummy empty "buffer"
  },
  decode: function decode(buffer, start, end) {
    // decode buffer here
    decode.bytes = 12; // another dummy value
    return {}; // dummy "decoded" object
  },
  encodingLength: encodingLength
};

let foo = codec.encode;
foo();
console.log(foo.bytes); // 5, as expected
console.log(codec.encode.bytes); // 5, as expected

let bar = codec.decode;
bar();
console.log(bar.bytes); // 12, as expected
console.log(codec.decode.bytes); // 12, as expected

【讨论】:

  • 谢谢!虽然bar.bytes 再次返回undefined。此外,codec.encode(); codec.encode.bytes 还返回undefined(它不应该根据Abstract Encoding Spec),所以很遗憾不是
  • @marceloneil 我已经更新了我的答案,请再看看。
  • 再次感谢!我以前试过这个,虽然我每个文件有多个编解码器(每个都需要一个encodingLength()。如果这是唯一的选择,我要么必须为每个编解码器创建一个文件,要么将定义的encodingLength()函数重命名为喜欢codecEncodingLength()
【解决方案2】:

保持简单,不要使用this

const codec = {
  encode() {
    codec.encode.bytes = 2;
    codec.encodingLength();
//  ^^^^^
  },
  encodingLength() {},
};

【讨论】:

    【解决方案3】:

    你可以这样做:

    const Codec = (function() {
        let bytes = 2;
        return {
            encode,
            encodingLength
        };
    
        function encode() {
            bytes++;
            encodingLength();
        }
    
        function encodingLength() {
            console.log(`bytes: ${bytes}`);
        }
    });
    
    const foo = new Codec();
    foo.encode(); // output: bytes: 3
    
    const bar = new Codec();
    bar.encode(); // output: bytes: 3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-10
      • 2013-03-06
      • 1970-01-01
      • 2015-08-04
      • 1970-01-01
      • 1970-01-01
      • 2017-12-11
      • 1970-01-01
      相关资源
      最近更新 更多