Cross-global instanceof

Andrea Giammarchi andrea.giammarchi at gmail.com
Thu Oct 31 18:46:15 PDT 2013


Allen, in which place on current known universe, when you parse a
JSON.string, your reviver function receives objects from another realm,
exactly?

That logic is bypassing and full-satisfying JSON.parse revival expectations
returning object later on checked as instanceof String in order to
differentiate and revive them differently and the same is done for Object,
where `typeof` would create a disaster in that tested logic with just a
`null` value plus CircularJSON is fully compatible with ES3 and Mr D.
Crockford JSON polyfill too so  .... since we'd like to have shimmable code
and Symbols are a no-go, do you still think instanceof is not needed at all?

'cause just this `null instanceof Object` is a good reason to use it when
objects are expected in a revival loop, imho.

Thanks, regardless, for spending some time on it.

Cheers


On Thu, Oct 31, 2013 at 5:50 PM, Allen Wirfs-Brock <allen at wirfs-brock.com>wrote:

>
> On Oct 31, 2013, at 2:56 PM, Andrea Giammarchi wrote:
>
> Sorry, secure was actually "reliable", as being secure about the type, not
> about security itself.
>
> A case where I do use instanceof is, example, with new String to easily
> decide later on what to do with such object that should not be treated as
> such.
>
> The script does resolve circular dependencies backward and forward out of
> JSON.stringiy and JSON.parse that do create objects from the current realm.
>
> Nothing else than `instanceof` is as usable/useful in current ESX spec for
> same purpose in terms of performance and reliability.
>
>
> https://github.com/WebReflection/circular-json/blob/master/src/circular-json.js#L108
>
> Just one case, still `instanceof` is used a lot and usually for good
> reasons, ...
>
>
> Well I promised I'd explain how I'd eliminate use of 'instanceof' so here
> goes. Note that since this is in the context of talking about possible ES
> extensions I'll assume those are available.
>
> First, you're using (lines 20) String wrapper objects(with the name String
> aliased to $String)  to pass around string values that require special
> processing.  Personally, I find this a little too subtle.  In ES6 I'd do
> this way instead:
>
> const isSpecialString = Symbol.for("isSpecialString");  //registration
> proposal in
> http://esdiscuss.org/topic/comments-on-sept-meeting-notes#content-76
> class SpecialString extends String {
>    constructor(str) {
>        super(str.slice(1)) //move string preprocessing into constructor
>    }
>    [isSpecialString]() {return isSpecialString in this};  //not really
> intended to be called
> }
>
> In line 110 I'd use
>     Array.isArray(current)
> instead of
>     current instanceof Array
> (note that JSON processing was one of the original use cases that
> motivated Array.isArray)
>
> In line 114, instead of
>  current instanceof $String ?
> i'd use
>  isSpecialString in  current ?    //note works cross-realm, if that is
> what is desired.
>
> I may be missing something WRT possible cross-realm issues, but in line
> 126 I'd replace
>    current instanceof Object
> with
>    typeof current ==  'object'
> but, I'm really thinking that I must be missing something that motivated
> your use of instanceof.  Is the supposed to be a Realm check?
>
> ... not because we are all bad developers (I hope ...)
>
>
> No, but possibly developers who learned (or were taught be people who
> learned) about such things in a language context where static nominal class
> tests make more sense.
>
> Allen
>
>
>
>
>
> Cheers
>
>
>
> On Thu, Oct 31, 2013 at 2:32 PM, Allen Wirfs-Brock <allen at wirfs-brock.com>wrote:
>
>>
>> On Oct 31, 2013, at 1:58 PM, Andrea Giammarchi wrote:
>>
>> I think the question is legit and this is a weak check
>>
>> `'throw' in possibleGenerator`
>>
>> specially if you have Dictionary like objects around ...
>>
>>
>> And why would such an object be passed into a context where you expect to
>> have a generator?  That would probably be an upstream bug and cause a
>> downstream failure.  Presumably you should have tests that look for such
>> failures.
>>
>>
>> 'length' in object does not tell you much, does it?
>>
>> who is that relevant?  If you need to condition something on the
>> existence of a length property, you can.  But in most situations you don't
>> want to do such tests.  Just access the property and use it/call it.  It it
>> is the right kind of object things will work.  If it is the wrong kind, it
>> is somebody's bug.
>>
>> `Object.prototype.toString` is abused all over client/server
>> libraries/utilities since ducks sometimes might look like gooses too.
>>
>>
>> Any, quite likely, most commonly used for unnecessary nominal type tests.
>>
>> So eventually would you don't want developers to really know what they
>> are dealing with and promote weak feature detections instead? It might
>> work, but that ain't secure.
>>
>>
>> Yes, no. Good OO is about letting go of knowledge of an objects
>> implementation.  In most cases you should only be concerned about the
>> object behavior you will use and not care about who implemented it or how
>> or whether or not there are multiple interoperable implementations
>> operating.  But you should be feature testing for the behavior you depend
>> upon.  Just invoke it.  It the method need isn't there you are usually
>> going to get an exception, typically sooner that latter.   Feature
>> detection shouldn't be  used as poor-man nominal type checking (where you
>> throw if it fails).  You should only use feature checking, when you have
>> real alternative paths to take depending upon the presence of the feature.
>>
>> "Secure"?  What kind of security for what purpose? Every little about JS
>> is secure.
>>
>> Of course, there really are some places where you really do need to do a
>> brand check for a specific object implementation.   In those cases, the
>> implementation of the object should include brand checking in its design
>> and expose an appropriate function for doing the check.  But a general
>> purpose mechanism is an attractive nuisance, and probably doesn't actually
>> do the check you need for your specific use case.
>>
>>
>> I still prefer `instanceof` for better performance since I don't usually
>> work with different realm but I also would like to have an
>> `Object.is(SomeClass, object);` facility instead of the boring, slow, and
>> inappropriate `{}.toString.call(obj)` check.
>>
>>
>> Show me real use cases and I'll try to explain with the check isn't
>> needed.
>>
>> Allen
>>
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20131031/c5804a58/attachment-0001.html>


More information about the es-discuss mailing list