I am doing source code reading for node-fetch, a JavaScript package.
I have two questions about the code for the function isRequest below.
const INTERNALS = Symbol('Request internals');
/**
* Check if `obj` is an instance of Request.
*
* @param {*} object
* @return {boolean}
*/
const isRequest = object => {
return (
typeof object === 'object' &&
typeof object[INTERNALS] === 'object'
);
};
https://github.com/node-fetch/node-fetch/blob/main/src/request.js
Am I correct in my understanding that
const INTERNALS = Symbol('Request internals');
defines a string?When I run the same code in local, the result is false, which is not what I expected. Why is this?
const INTERNAL = Symbol('Request Internal');
const isRequest = object => {
return (
typeof object === "object" &&
typeof object[INTERNAL] === "object"
);
}
const req = new Request("https://example.com");
console.log(isRequest(req));
❯ node -v
v18.11.0
❯ node test.js
false
CodePudding user response:
Am I correct in my understanding that
const INTERNALS = Symbol('Request internals');
defines a string?
No, it defines a Symbol
When I run the same code in local, the result is false
This is expected because...
Note that
Symbol("foo")
does not coerce the string"foo"
into a Symbol. It creates a new Symbol each time
Symbols, just like objects are not equal even if they look identical. The "Request internals" symbol used in Request
is not the same as the one you created in INTERNAL
const THEIR_SYMBOL = Symbol("foo");
const obj = {
[THEIR_SYMBOL]: "some value",
};
console.log("THEIR_SYMBOL:", obj[THEIR_SYMBOL]); // "some value"
const MY_SYMBOL = Symbol("foo");
console.log("MY_SYMBOL:", obj[MY_SYMBOL]); // undefined
CodePudding user response:
Symbols are supposed to be unique. The string supplied is just supposed to be a tag on invocation, so you know its purpose. It is guaranteed to be unique. So, generating a new symbol means generating a new unique identifier - even if you use the same tag. A symbol may be a hashed string, but the object itself may have an internal hash, not corresponding to the hashed tag or the tag may be hashed irretrievably. It is it's own type. And the use is that if you keep your symbol around, youre guaranteed to access the symbols data if you keep your copy of the symbol and use it as a means of retrieving the associated data. Symbol.for maps to the instance you created initially. Id rather use Symbol.for tho, since it also creates a new symbol. because, it wont be retrievable if you dont keep it around. but using symbol.for you get the global instance of that tag.