函数未在Object.keys或Object.getOwnPropertyNames下列出,但可以调用

时间:2016-05-19 09:57:32

标签: javascript node.js object

假设有一些库javascript对象jsObj。在调用Object.keysObject.getOwnPropertyNames时,我会获得一个属性列表,例如

[a,b,c,d]

但我仍然可以调用类似jsObj.e()的函数。为什么方法e不属于Object.keysObject.getOwnPropertyNames?他们是怎么做的?

Here,它说Object.getOwnPropertyNames也会返回不可枚举的属性。那么上面的e属性的特征是什么呢?

我正在使用opentok服务器端SDK。使用以下代码

var OpenTok = require('opentok');
var opentok = new OpenTok(config.tokbox.apiKey, config.tokbox.secret);
console.log("opentok1", Object.getOwnPropertyNames(opentok));
prints -> // [ '_client',
  'apiKey',
  'apiSecret',
  'apiUrl',
  'startArchive',
  'stopArchive',
  'getArchive',
  'deleteArchive',
  'listArchives' ] 
console.log("opentok2", opentok.createSession);
prints -> function (...){...}

2 个答案:

答案 0 :(得分:5)

必须在对象的原型上定义

Object.e。像这样:

var test = function() {}
test.prototype = { e: function() { return 'e'; } }
var obj = new test();
Object.keys(obj) // returns []
obj.e() // returns 'e'

获取原型键的一种方法就是获取原型并使用Object.keys()函数:

Object.keys(Object.getPrototypeOf(obj))

然而,这将不会为您提供原型原型的键。

答案 1 :(得分:2)

JS对象的原则可能是

  • own - 意味着它直接在对象上定义
  • inherited - 该属性是可调用的,但是在prototype(Object predecessor)
  • 中定义
  • enumerable / not enumerable - 某些属性(如length)不可枚举,您可以使用Object.defineProperty()
  • 定义自己的非可枚举属性

然后迭代函数适用于此属性的某个子集:

所以这个函数都没有迭代继承的属性。如果您想在不解决所有权问题的情况下迭代所有属性,那么您需要for... in cycle,例如:

var keys = [];
for (var key in object)
    keys.push(key);

但这不会迭代不可枚举的属性。

有关所有权和可枚举性的完整概述see this documentation