I did a
console.log(myURL);
and did not see the extension property
console.log(myURL.extension);
but if I log it on it's own it correctly shows the value.
found is a URL object created as such:
const url = require('url');
let myURL = new URL(test);
the missing property was added as such:
myURL.extension = test.split('.').pop();
The output looks like this:
URL {
href: 'https://www.imdb.com/favicon.ico',
origin: 'https://www.imdb.com',
protocol: 'https:',
username: '',
password: '',
host: 'www.imdb.com',
hostname: 'www.imdb.com',
port: '',
pathname: '/favicon.ico',
search: '',
searchParams: URLSearchParams {},
hash: ''
}
Example code:
const url = require('url');
const test = 'https://www.imdb.com/favicon.ico';
let myURL = new URL(test);
myURL.extension = test.split('.').pop();
console.log(myURL);
The reason for this behavior is because the prototype
of URL
defines autil.inspect.custom
override. In Node.js v12.11.0 for example, it's defined like this:
> console.log(myURL[util.inspect.custom])
[inspect.custom](depth, opts) {
if (this == null ||
Object.getPrototypeOf(this[context]) !== URLContext.prototype) {
throw new ERR_INVALID_THIS('URL');
}
if (typeof depth === 'number' && depth < 0)
return this;
const ctor = getConstructorOf(this);
const obj = Object.create({
constructor: ctor === null ? URL : ctor
});
obj.href = this.href;
obj.origin = this.origin;
obj.protocol = this.protocol;
obj.username = this.username;
obj.password = this.password;
obj.host = this.host;
obj.hostname = this.hostname;
obj.port = this.port;
obj.pathname = this.pathname;
obj.search = this.search;
obj.searchParams = this.searchParams;
obj.hash = this.hash;
if (opts.showHidden) {
obj.cannotBeBase = this[cannotBeBase];
obj.special = this[special];
obj[context] = this[context];
}
return inspect(obj, opts);
}
You could override this behavior and add the extension
property as a getter to the URL
class's prototype
if you really cared about the output format:
const { URL } = require('url');
const { inspect } = require('util');
Object.defineProperty(URL.prototype, 'extension', {
enumerable: true,
configurable: true,
get() { return this.pathname.split('.').pop(); }
});
URL.prototype[inspect.custom] = function(depth, opts) {
if (typeof depth === 'number' && depth < 0) return this;
const keys = Object.keys(URL.prototype).filter(key => typeof this[key] !== 'function');
const obj = Object.create({ constructor: URL });
Object.assign(obj, ...keys.map(key => ({ [key]: this[key] })));
return inspect(obj, opts);
};
and then your output format will look like this:
> new URL('https://www.imdb.com/favicon.ico')
URL {
href: 'https://www.imdb.com/favicon.ico',
origin: 'https://www.imdb.com',
protocol: 'https:',
username: '',
password: '',
host: 'www.imdb.com',
hostname: 'www.imdb.com',
port: '',
pathname: '/favicon.ico',
search: '',
searchParams: URLSearchParams {},
hash: '',
extension: 'ico'
}
However, if you don't care that much then you can just accept that the output format you see is the expected behavior, and you can access the extension
property just as you normally would on any other object.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.