无法从绑定函数访问对象变量,或从未绑定函数访问内部方法

Unable to access object variable from bound function, or internal method from unbound function

仅供参考,我正在尝试遵循 Abstract Encoding 规范。本质上,我想创建一个 "function variable" 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 () { }
}

这对你有用吗?

// 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

保持简单,不要使用 this:

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

你可以这样做:

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