节点的控制台未显示所有对象属性……这是预期的行为吗?

时间:2019-12-15 20:55:25

标签: javascript node.js

我做了

  console.log(myURL);

并且没有看到扩展属性

  console.log(myURL.extension);

但是如果我自己登录,它将正确显示该值。

found是这样创建的URL对象:

  const url = require('url');
  let myURL = new URL(test);

缺少的属性是这样添加的:

  myURL.extension = test.split('.').pop();

输出看起来像这样:

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: ''
}

示例代码:

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);

1 个答案:

答案 0 :(得分:1)

此行为的原因是因为URLprototype定义了util.inspect.custom覆盖。例如,在Node.js v12.11.0中,它的定义如下:

> 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);
}

如果您真的很关心输出格式,则可以覆盖此行为并将extension属性作为吸气剂添加到URL类的prototype中, / p>

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);
};

,然后您的输出格式将如下所示:

> 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'
}

但是,如果您不太在意,那么您可以接受所看到的输出格式是预期的行为,并且可以像平常对任何其他对象一样访问extension属性。