无法从绑定函数访问对象变量,或从未绑定函数访问内部方法
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
仅供参考,我正在尝试遵循 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