With custom exceptions, we have to create a new instance before we throw them: function AppError(msg) { this.msg = msg; // just an example } throw new AppError("I did bad"); To throw a StopIteration, on the other hand, we have to throw it directly: throw StopIteration; // object StopIteration throw new StopIteration(); // TypeError With Error, both are possible: throw Error("oops"); // object Error throw new Error("oops"); // object Error I've seen both forms a number of times now. AppError and Error are functions (StopIteration is an object), so I'd normally say "throw new Error()" was the preferred form. We couldn't just "throw AppError(msg)" because that would set |msg| on the global object, but this doesn't happen with Error, so "throw Error(msg)" should be ok. Any thoughts about this? (BTW, StopIteration is a rather unusual object: it can't be called or instanced, but is apparently an instance of itself. StopIteration instanceof StopIteration == true) - Conrad
![]() |
0 |
![]() |
Conrad Lender wrote: > With Error, both are possible: > > throw Error("oops"); // object Error > throw new Error("oops"); // object Error > > I've seen both forms a number of times now. AppError and Error are > functions (StopIteration is an object), so I'd normally say "throw new > Error()" was the preferred form. We couldn't just "throw AppError(msg)" > because that would set |msg| on the global object, but this doesn't > happen with Error, so "throw Error(msg)" should be ok. Any thoughts > about this? The spec (ECMAScript edition 3) says: "15.11.1 The Error Constructor Called as a Function When Error is called as a function rather than as a constructor, it creates and initialises a new Error object. Thus the function call Error(…) is equivalent to the object creation expression new Error(…) with the same arguments." so with Error you are free to do Error(...) or new Error(...) -- Martin Honnen http://msmvps.com/blogs/martin_honnen/
![]() |
0 |
![]() |
Conrad Lender wrote: > With custom exceptions, we have to create a new instance before we throw > them: > > function AppError(msg) { > this.msg = msg; // just an example Yes, this.message would be better. > } > throw new AppError("I did bad"); > > To throw a StopIteration, on the other hand, we have to throw it directly: > > throw StopIteration; // object StopIteration > throw new StopIteration(); // TypeError > > With Error, both are possible: > > throw Error("oops"); // object Error > throw new Error("oops"); // object Error > > I've seen both forms a number of times now. AppError and Error are > functions (StopIteration is an object), so I'd normally say "throw new > Error()" was the preferred form. We couldn't just "throw AppError(msg)" > because that would set |msg| on the global object, but this doesn't > happen with Error, so "throw Error(msg)" should be ok. Any thoughts > about this? In addition to Martin's answer: ISTM any constructor C can be enabled to be a factory with var _global = this; function C() { var me = arguments.callee; if (this.constructor != me) { var x = new C(); me.apply(x, arguments); return x; } } under the provision that C() does not throw exceptions if not enough arguments are passed (else an iteration of eval("me(...)") would be required). > (BTW, StopIteration is a rather unusual object: it can't be called or > instanced, but is apparently an instance of itself. StopIteration > instanceof StopIteration == true) What is the purpose of this object? PointedEars
![]() |
0 |
![]() |
Thomas 'PointedEars' Lahn wrote: [...] > In addition to Martin's answer: ISTM any constructor C can be enabled to be > a factory with > > var _global = this; > > function C() > { > var me = arguments.callee; > > if (this.constructor != me) > { > var x = new C(); > me.apply(x, arguments); > return x; > } > } It's interesting how this snippet can be fooled, since it relies on a public `constructor` property of an object that constructor is being called in a context of :) function Person() { var me = arguments.callee; if (this.constructor != me) { var x = new C(); me.apply(x, arguments); return x; } this.name = name; } Person.call({ constructor: Person }, 'foo'); // undefined This is a bogus call of course, but it breaks a premise that constructor will return a newly constructed object. [...] -- kangax
![]() |
0 |
![]() |
kangax wrote: > Thomas 'PointedEars' Lahn wrote: >> In addition to Martin's answer: ISTM any constructor C can be enabled to be >> a factory with >> >> var _global = this; >> >> function C() >> { >> var me = arguments.callee; >> >> if (this.constructor != me) >> { >> var x = new C(); Should have been `me' instead of `C'. That is, if one wants to remove the dependency on the declared identifier. Else `C' should be used instead of `me' everywhere here. >> me.apply(x, arguments); >> return x; >> } >> } > > It's interesting how this snippet can be fooled, since it relies on a > public `constructor` property of an object that constructor is being > called in a context of :) [...] Yes, of course. In languages as dynamic as these, there are few guarantees. One cannot even guarantee that me.apply(...) will work as intended even if `constructor' is right because it may not be supported or be overwritten by bogus code. PointedEars
![]() |
0 |
![]() |
On 06/06/09 15:31, Thomas 'PointedEars' Lahn wrote: > Conrad Lender wrote: > In addition to Martin's answer: ISTM any constructor C can be enabled > to be a factory with [snip] Interesting pattern. It's probably not how Error is implemented internally (toSource contains "[native code]", at least in FF), but it's similar. >> (BTW, StopIteration is a rather unusual object: it can't be called >> or instanced, but is apparently an instance of itself. >> StopIteration instanceof StopIteration == true) > > What is the purpose of this object? It's used with Iterators to signal a 'stop' condition: https://developer.mozilla.org/En/Core_JavaScript_1.5_Guide/Iterators_and_Generators - Conrad PS: I forgot to thank Martin for his reply, which was spot on. I really should have thought of that myself.
![]() |
0 |
![]() |
Conrad Lender wrote: > Thomas 'PointedEars' Lahn wrote: >> Conrad Lender wrote: >> In addition to Martin's answer: ISTM any constructor C can be enabled >> to be a factory with [snip] > > Interesting pattern. It's probably not how Error is implemented > internally (toSource contains "[native code]", at least in FF), I wonder why you think that `toSource' is even relevant. First of all, it is a proprietary JavaScript method (not defined in, but allowed by ECMAScript) and secondly, it contains "[native code]" for *all* native methods, with "native" meaning "not user-defined" here. > but it's similar. In fact, reviewing this I think my implementation is unnecessary complicated and error-prone for most cases. Since we usually know the maximum number of arguments the method would handle, and their identifiers per declaration, the following (here for zero arguments) should suffice: function C() { var me = arguments.callee; if (this.constructor != me) { return new C(); } } For the Error object as specified in ES3F that would mean function Error(message) { if (this.constructor != arguments.callee) { return new Error(message); } } Of course, this should only be considered pseudo-code with regard to the ECMAScript implementation and the language it would be written in (probably C++, as in SpiderMonkey, or Java, as in Rhino). >>> (BTW, StopIteration is a rather unusual object: it can't be called >>> or instanced, but is apparently an instance of itself. >>> StopIteration instanceof StopIteration == true) >> What is the purpose of this object? > > It's used with Iterators to signal a 'stop' condition: > https://developer.mozilla.org/En/Core_JavaScript_1.5_Guide/Iterators_and_Generators The Matrix has you. PointedEars
![]() |
0 |
![]() |
Conrad Lender wrote: > Thomas 'PointedEars' Lahn wrote: >> Conrad Lender wrote: In addition to Martin's answer: ISTM any >> constructor C can be enabled to be a factory with [snip] > > Interesting pattern. It's probably not how Error is implemented > internally (toSource contains "[native code]", at least in FF), I wonder why you think that `toSource' is even relevant. First of all, it is a proprietary JavaScript method (not defined in, but allowed by ECMAScript) and secondly, it contains "[native code]" for *all* native methods, with "native" meaning "not user-defined" here. > but it's similar. In fact, reviewing this I think my implementation is unnecessary complicated and error-prone for most cases. Since we usually know the maximum number of arguments the method would handle, and their identifiers per declaration, the following (here for zero arguments) should suffice: function C() { var me = arguments.callee; if (this.constructor != me) { return new me(); } } For the Error object as specified in ES3F that would mean function Error(message) { var me = arguments.callee; if (this.constructor != me) { return new me(message); } } Of course, this should only be considered pseudo-code with regard to the ECMAScript implementation and the language it would be written in (probably C++, as in SpiderMonkey, or Java, as in Rhino). >>> (BTW, StopIteration is a rather unusual object: it can't be called or >>> instanced, but is apparently an instance of itself. StopIteration >>> instanceof StopIteration == true) >> What is the purpose of this object? > > It's used with Iterators to signal a 'stop' condition: > https://developer.mozilla.org/En/Core_JavaScript_1.5_Guide/Iterators_and_Generators The Matrix has you! Regards, PointedEars
![]() |
0 |
![]() |
On 07/06/09 01:34, Thomas 'PointedEars' Lahn wrote: > I wonder why you think that `toSource' is even relevant. First of > all, it is a proprietary JavaScript method (not defined in, but > allowed by ECMAScript) and secondly, it contains "[native code]" for > *all* native methods, with "native" meaning "not user-defined" here. ad "first") I was referring to Firefox in this case (I mentioned that). ad "second") Yes, that's what I meant. I'm not going to dig into the mess that is Firefox's source code now, but I'm pretty sure that Error is implemented in C++ instead of JavaScript. >>>> [StopIteration] >>> What is the purpose of this object? >> It's used with Iterators to signal a 'stop' condition: >> https://developer.mozilla.org/En/Core_JavaScript_1.5_Guide/Iterators_and_Generators > > The Matrix has you. Nice. Did you ever consider extending the matrix to DOM features? It would mean a lot of extra effort, but it would make for a very useful reference page. I'd be glad to help should you decide to do this. - Conrad
![]() |
0 |
![]() |
Conrad Lender wrote: > Thomas 'PointedEars' Lahn wrote: >> I wonder why you think that `toSource' is even relevant. First of >> all, it is a proprietary JavaScript method (not defined in, but >> allowed by ECMAScript) and secondly, it contains "[native code]" for >> *all* native methods, with "native" meaning "not user-defined" here. > > ad "first") > I was referring to Firefox in this case (I mentioned that). I've seen that. You haven't answered my question. > ad "second") > Yes, that's what I meant. I'm not going to dig into the mess that is > Firefox's source code now, but I'm pretty sure that Error is implemented > in C++ instead of JavaScript. So, as we know (or should know) that `Error' is an ECMAScript native object, and do not assume that SpiderMonkey is written in JavaScript, why is the return value of this proprietary method relevant *at all*? >>>>> [StopIteration] >>>> What is the purpose of this object? >>> It's used with Iterators to signal a 'stop' condition: >>> https://developer.mozilla.org/En/Core_JavaScript_1.5_Guide/Iterators_and_Generators >> The Matrix has you. > > Nice. Did you ever consider extending the matrix to DOM features? Yes, I did. I can upload a preliminary version of the DOM Support Matrix if you are interested. > It would mean a lot of extra effort, but it would make for a very useful > reference page. I'd be glad to help should you decide to do this. Duly noted. PointedEars
![]() |
0 |
![]() |
On 07/06/09 02:12, Thomas 'PointedEars' Lahn wrote: > Conrad Lender wrote: >> Thomas 'PointedEars' Lahn wrote: >>> I wonder why you think that `toSource' is even relevant. I don't want to argue about this any more. I have the feeling we both mean the same thing anyway, and are only quibbling about semantics. What's more important: >>> The Matrix has you. >> >> Nice. Did you ever consider extending the matrix to DOM features? > > Yes, I did. I can upload a preliminary version of the DOM Support > Matrix if you are interested. I'm very interested. >> It would mean a lot of extra effort, but it would make for a very >> useful reference page. I'd be glad to help should you decide to do >> this. > > Duly noted. If you'd like to delegate some of the work, you can contact me per email; just replace 'yahoo' with 'gmail' (I only check the Yahoo account about once a month). I also read the group (obviously ;-), in case you want to organize this here. - Conrad
![]() |
0 |
![]() |