Comments (10)
It means "If Type(x
) is Object", as we are talking about spec-level semantics here. There is no other meaning of "object" that could be relevant in this context.
The "or function" addendum was put there as a gentle reminder that all functions are objects as well, i.e. that the callability of x
doesn't matter.
Your (4) expression is an implementation of the predicate, but not more than that. There are many other possible implementations, and none should be used in the specification.
from promises-spec.
@bergus, thanks for your reply and helpful links.
I know your wikipedia link was at least half-joking, but I do want to point out in seriousness that there are at least 3 different meanings of "object" in the context of javascript, and it doesn't look to me like the ECMAScript 2105 spec is very successful at sorting them out.
It means "If Type(x) is Object", as we are talking about spec-level semantics here. There is no other meaning of "object" that could be relevant in this context.
Perhaps that's true, but it's not at all obvious to me, even after you pointed it out and after I've gone over sections 4 and 6 of the ECMAScript spec to which you referred. In particular, my (1) and (2) still look like pretty good guesses to me, aside from the fact that the compliance test suite flunks them (which could actually be a bug in the test suite, for all I know).
I doubt I'm alone in this, among your intended audience of promise implementers.
Your (4) expression is an implementation of the predicate, but not more than that. There are many other possible implementations,
I'd be interested to see some of the "many other possible implementations" you have in mind, if you care to share. I only know of (4), and I got that by fumbling around in the dark til the test passed.
and none should be used in the specification.
Can you say more about why you feel that none of them should be mentioned? From my point of view, spelling out one of them for definiteness sure sounds like a good thing-- it would have saved me a substantial amount of time and aggravation.
from promises-spec.
Actually, my reading of Table 35 is that my (4) is not a valid test for the Object type after all, despite the fact that the compliance test suite passes it. The reason I believe (4) isn't valid is that, according to the last line of that table, if x
is an "Object (non-standard exotic and does not implement [[Call]])" it might be that typeof(x)
is "foobar"
. In that case (4) will wrongly conclude x
is not an Object.
Please confirm.
from promises-spec.
In fact, it looks to me like Table 35 completely nails down the relationship between Object-ness and the typeof
operator.
This appears to be more solid than I previously thought.
So, it looks to me like the following is a (the?) correct test for Object-ness:
x !== null &&
typeof x !== "undefined" &&
typeof x !== "boolean" &&
typeof x !== "number" &&
typeof x !== "symbol" &&
typeof x !== "string"
Assuming I have that right so far,
this is the only correct test for Object-ness that I know of at this time: my (1),(2),(3),(4) are all wrong, the compliance test suite's characterization is wrong, and I'll go out on a limb and say that I suspect some or all of the other "many possible implementations" that @bergus has in mind are wrong too. Of course I'm willing to be proven wrong :-)
It may be that there is an alternative implementation that uses instanceof
in some way;
I don't know since I got lost trying to follow the discussion of instanceof
in the ECMAScript spec.
from promises-spec.
I had Object(o) === o
in mind, which is the other (next to 4) idiomatic test for object-ness in JavaScript. That they differ about special host objects doesn't really matter, because host objects which overwrite their typeof
behaviour don't want to be recognised as objects.
from promises-spec.
@bergus thanks for the example. Yes, it looks to me like Object(o)===o
is a correct test, according to the MDN doc:
The Object constructor creates an object wrapper for the given value.
If the value is null or undefined, it will create and return an empty object,
otherwise, it will return an object of a Type that corresponds to the given value.
If the value is an object already, it will return the value.
More material here: http://stackoverflow.com/questions/8511281/check-if-a-value-is-an-object-in-javascript . In particular, Oriol correctly points out that my proposed test using instanceof
from above (2 comments ago), while correct, isn't as good as your Object(o)===o
since mine will break if a future standard introduces a new primitive type.
Idiomatic (I guess that means "commonly used"?) or not, (4) is simply wrong according to the ECMAScript spec that you claim to be following.
Since you're insisting that promise/A+ spec's object means ECMAscript spec's notion of Object from part 6, and that's the only thing it could possibly mean, don't you think you should actually adhere to that definition? Otherwise it keeps looking like you're making up rules and exceptions as you go along
and then expecting people to read your mind.
That they differ about special host objects doesn't really matter, because host objects which overwrite their typeof behaviour don't want to be recognised as objects.
That sentence really doesn't hold up very well at all.
Two immediate objections:
(I) Such objects don't want that? Really? All of them? That's a bold thing to say, isn't it? I admit I'm not familiar with the context we're talking about, but it seems really odd to be making a claim about the wants of every object fitting this description that anyone might ever write, so I'm skeptical.
(II) If indeed you're right that some/most/all such objects don't want to be recognized as objects (which I read as "want to be treated as non-objects" per common English usage), then won't they be disappointed when your test Object(x)===x
correctly identifies them as objects? Especially ones that also happen to be thenables, which will find that different promise libraries actually treat them differently.
Don't you think it would be better to actually follow and enforce the definition of Object that you're citing, instead of coming up with reasons to do some other thing based on presumptions of what all pathological objects want and shaky logic? The definition is actually looking fairly clear to me now, to my surprise.
I believe it's clear at this point that (4) simply fails to comply with the promises/A+ spec,
while the compliance suite lets it pass.
This inconsistency could be resolved in one of two ways:
(A) fix the compliance suite so that it correctly flunks (4), as required by the spec,
or,
(B) change the spec to allow (4), so that it will agree with the compliance suite.
I don't have a preference.
In any case, I'd also strongly recommend addressing the original issue, as follows:
- Mention (perhaps even recommend)
Object(x)===x
. There are evidently lots of ways to do it right and lots of ways to do it wrong; mentioning this simple right way would be significantly helpful in guiding implementers toward success. - Also mention that "object" is being used as in the ECMAscript spec section 6. That's nowhere near as obvious as you've made it out to be, to many of the people of varying levels of javascript expertise who make up your audience. Referring to the ECMAscript spec would go a long way towards clearing the fog, as it did when you linked to it in this thread.
from promises-spec.
These objects you are talking about are ignored because they're basically non-existent. They are absolutely non-standard, and while the ES spec does permit them it explicitly discourages implementations from using them.
This is also the reason why the compliance suite doesn't test them: there's no way to create such an object in node.js.
The only examples that come to my mind are document.all
and some host objects from the IE7 era (like ActiveX
), which were also known for not returning "function"
despite being callable. Nobody gives a f*** about them, and none of them is thenable anyway.
The other reason why x != null && (typeof x == "object" || typeof x == "function")
is commonly used over Object(x) === x
is that it is significantly faster, not involving a global function call.
from promises-spec.
@bergus, thanks, good to know all these things.
Well, I guess flunking (4) isn't really an option then. In that case it would be great if the spec could be changed to match the suite. Not that I give a f*** about those objects, it's just that if there wasn't this apparent hole in the logic, it would have saved me from worrying or thinking much about it; likewise for others in my position in the future, and people out on the web who are trying to make sense of the spec.
In chrome: document.all.then = function(){}
. Now it's a thenable. :-) Whatever.
Yeah, the lack of any efficient bulltetproof way to ask is-an-object is pretty bizarre.
And, isn't Object(x) more than just a function call-- it actually creates a new object in memory (in the case x wasn't an object), right? That sounds like quite a big deal for something that should be a lightweight check; but maybe it's not as big a deal in javascript as it is in C++, I'm not sure. On the other hand I suppose a javascript compiler/interpreter could optimize Object(x)===x
into something that's even more efficient than x != null && (typeof x == "object" || typeof x == "function")
, couldn't it?
from promises-spec.
Actually... it looks like document.all
isn't an example of the last line of Table 35 for which typeof doesn't return "object"
.
From typeof doc on MDN:
All current browsers expose a non-standard host object document.all with type Undefined.
typeof document.all === 'undefined';
Although the specification allows custom type tags for non-standard exotic objects,
it requires those type tags to be different from the predefined ones.
The case of document.all having type tag 'undefined' must be classified as an
exceptional violation of the rules.
So, as far as I know, neither nodejs nor chrome has any way of creating an object whose behavior is described by the last line of Table 35 and whose typeof doesn't return "object"
. Basically non-existent, as you say.
from promises-spec.
I second @donhatch that this should be specified. The definition of thenable
aims directly at specifying duck typing tests:
2.3. It introduces the term “thenable” as distinct from “promise”, so as to more precisely talk about the duck-typing tests necessary for implementation interoperation.
The definition uses this language:
1.2. “thenable” is an object or function that defines a then method.
Yet how to correctly detect "is an object or function" is left unclear. Referencing abstract operations in the ECMAScript spec is reasonable, and if that's the intention it should be explicit.
from promises-spec.
Related Issues (20)
- Can you assist me in satisfying promises aplus spec 2.2.4 in NodeJS? HOT 4
- here is a Chinese translation HOT 1
- Confused terminology: resolve and fulfill HOT 3
- Proposal: Make clear in the spec that the Promise constructor runs the provided function body immediately HOT 1
- Relationship with ECMA-262 § 25.4.2 - Promise Jobs HOT 4
- What is the intention behind clause 2.2.4 of Promise/A+ spec? HOT 5
- change "if x is a promise" to something non-circular and clear HOT 7
- Clarify ambiguity between promises and thenables w.r.t. 2.3.2.1? HOT 5
- Promise Resolution Procedure 3.iii: What if then never calls its arguments? HOT 2
- UnhandledPromiseRejectionWarning HOT 3
- Some imprecise points in this spec HOT 22
- Question about **promise resolution procedure** 2.3.2 HOT 2
- Adopting state without .then() HOT 2
- Support translation
- What happened? please see code
- please see code HOT 1
- Rust promise implementation
- Add my implementation of promises
- Confused about the point of 2.3.2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from promises-spec.