Jan Bruns wrote:
> Thomas 'PointedEars' Lahn:
>> Jan Bruns wrote:
>>>> For example, there is a reason why I enclosed the host object property
>>>> access in a “try” block.
>>> What is that reason? Does "typeof" throw on any enumerated property
>>> anywhere?
>> If you would have tried, you would have seen that
>>
>> typeof Object.getPrototypeOf(webGLcontext)[name] == "function"
>>
>> throws “TypeError: Illegal invocation” for the _enumerable_ properties
>> where
>
> Interesting. Saved me from thinking about how to create an object that
> throws on typeof(enumerated property). Maybe the "getters" can do so.
Most certainly. (Why the quotation marks?)
> But we're talking about a very popular API, meaning there are thousands
> or maybe even a million programmers out there that tried out or will try
> out working with it.
The generally recommended approach is the one that I recommended to you
initially: create a wrapper for the host object. Obtaining, and operating
on, the keys of the object is just one of the more convenient
implementations of that approach.
> The prototype object of such an API of course might have very browser
> specific behaviour that isn't spcificly user friendly (and even doesn't
> necessarily have to meet programing language specific functionality), as
> long as the API's specification doesn't explicitly define such behaviour.
>
> But if
>
> for (var i in API) { typeof API[i] };
>
> would throw, why did they implement and enumerate that fail?
I repeat, you must differentiate between the programming language and the
APIs that can be used with it (see also the ECMAScript Support Matrix
referred to in my signature). The “typeof” operator is a *language*
feature. It was devised long before the host runtime environments were
conceived in which, and the APIs with which, it can potentially be used.
So in general, it is supposed to work with *native* objects; it may or may
not work with host objects such as WebGL context objects and their
prototypes. Also, because ECMAScript was an *afterthought*, the Language
Specification *specifies* the possibility for certain aberrant behavior
for host objects. This includes the “typeof” operation:
<
http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,
%201st%20edition,%20June%201997.pdf>, § 11.4.3
<
http://www.ecma-international.org/ecma-262/8.0/#sec-typeof-operator>
However, further testing in the same environment shows that only access to
some of the *prototype* properties fails, presumably because their getter
cannot handle access that is not to a properly initialized instance. This
would mean that a for-in statement on the instance is the only way, if less
efficient, to solve this using iteration with sufficient completeness.
Still, ISTM that the “try” block is mandatory in such a case as there are
other examples where accessing, including even only testing, the properties
of a non-prototype host object fails.
It is also possible that this prototype is designed to be extended, in which
case the iteration is unnecessary, and you can simply add the custom methods
to the prototype, so that they can be inherited by the instance. Simple
tests in the same environment support this assumption. Doing so would
certainly be safer than augmenting the instance itself (which I cannot be
sure from the code that you posted that you attempted it), but it needs more
testing.
> Well, probably for the same reasons, as
>
> Object.create(API);
>
> might not work as expected: work in progress.
I do not think so.
> But then, the only clean way to deal with it would be to copy&paste the
> API specification (like C headers) to any project that needs to inherit
> the API instead of just referencing it. […]
Not at all.