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

5
假设有一个名为jsObj的javascript库对象。调用Object.keysObject.getOwnPropertyNames,我会得到一个属性列表,例如:
[a,b,c,d]

但我仍然可以调用像jsObj.e()这样的函数。为什么方法e不是Object.keysObject.getOwnPropertyNames的一部分?他们是如何做到的?
这里,它说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 (...){...}

请分享可执行演示。无法理解问题的所在... - Rayon
3
这很可能是从其中一个原型继承而来的? 如果您执行以下操作:for(prop in obj) { console.log(prop); } (其中 obj 是您的对象),那么它会输出吗? - Arg0n
添加了一些代码,但由于需要您自己的 API 密钥,因此无法执行。希望这样可以清楚地解释问题。 - Aman Gupta
2个回答

6

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

然而,这将无法为您提供原型的原型的键。


有没有办法列出对象原型的所有属性? - Aman Gupta
请使用 "for in",因为它将列出对象及其原型继承的所有属性。 - evolutionxbox
更新了我的回答。你也可以像@evolutionxbox所说的那样使用for ... in,但如果你想要一个列表,那么你必须使用for ... in方法自己构建它。 - Emil Ingerslev
查看https://dev59.com/rHA75IYBdhLWcg3w3M9e,了解使用`for ... in`的好方法。 - Emil Ingerslev

3
一个JS对象的属性可以分为:
  • 自有属性 -- 直接在对象上定义的
  • 继承属性 -- 可以调用该属性,但是该属性是在原型(对象前身)中定义的
  • 可枚举/不可枚举 -- 一些属性(如length)不可枚举,您可以使用Object.defineProperty()定义自己的不可枚举属性
然后迭代函数仅适用于这些属性的某个子集: 因此,这些函数都不能迭代继承属性。如果您想迭代所有属性而不解析所有权,则需要使用for...in循环,例如:
var keys = [];
for (var key in object)
    keys.push(key);

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

有关所有权和可枚举性的完整概述,请查看此文档


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接