On Mar 15, 3:30 pm, "VK" <
[email protected]> wrote:
Using a try/catch with a timer seems to work. Do you see
any problems with this?
javascript:
var js=document.createElement('SCRIPT');
js.src='
http://localhost/hi.js';
document.getElementsByTagName('HEAD')[0].appendChild(js);
setTimeout(fn=function() {
try {
hi();
} catch(e) {
alert(e.Description);
setTimeout( 'fn()', 10 );
}
}
, 10 );
void(0);
P.S. In the form above the bookmarklet implements i) an
environment checks, ii) full void wrap against occasional
text garbage and iii) local shy namespace so do not pollute
Global beyond the necessity
<a href="javascript:void((function(){
if(window) {
var js=document.createElement('SCRIPT');
js.src='hi.js';
document.getElementsByTagName('HEAD')[0].appendChild(js);
}})())">link</a>
I would like to understand some of this better.
* environment checks - can you explain a bit more?
In order to explain anything it would be necessary to understand it, and
VK is not someone who understands javascript. What he may (and often
does) do is post a story laced with sufficient jargon (or jargon-like
statements) and sufficiently incoherently expressed that people who don't
know the subject may get the impression that he knows what he is talking
about (though will not learn anything) and (assuming he achieves his
usual level of incoherence) people who do understand the subject will not
know what he is talking about at all (else whenever he fails to achieve
sufficient incoherence his story would be subject to technical correction
(as may be observed from the archives of the group)).
is this the if(window) part?
It would make no sense to describe that as "environment checks". All web
browsers provide a property of the global object with the name 'window'
the value of which refers to the global object itself. So - if(window){
.... } - implies resolving the Identifier - window - and then
type-converting the resulting value into a boolean value and using that
boolean value to determine whether to execute the block statement that
follows the - if - test expression. The global object will type-convert
to boolean true and so the block will be executed.
However, in the event that this code was exposed to an environment where
the browser had not provided a 'window' property of the global object
(and no such environments have ever been identified in a web browser
(though non-browser environments such as ASP are not expected to provide
such a property)) the test would not result in the identifier - window -
type-converting to boolean false. Instead the attempt to type-convert the
result of resolving - window - (which would not resolve as no - window -
property of the global object would exist) would result in a runtime
error.
Thus the outcome of the "check" would be either its being passed and the
code in the block executed (the expected outcome in all browser
environments) or a runtime error. Which is effectively the same as the
expected outcome if the test was omitted entirely (the code is executed
and either errors or it does not).
The - if(window){ ... } - is a mystical incantation, and like all good
mystical incarnation structures seen in javascript code it appears
precisely because it is both useless and harmless. The only consequence
of understanding it is that it would then be seen as useless and omitted
entirely.
In general code exposed to an unknown browser environments tests might
verify the availability of the - createElement -, -
getElementsByTagName - and - appendChild - methods actually used by the
code, as they are known not ot exist in all browser environments and so
testing for them may avoid provoking runtime errors that would follow
from their use in such environments (allowing the script to fail to act,
or use fall-back strategies, under its own control). In the context of
bookmarklet/favelet type scripts that level of testing is redundant as
you know the browser environment you are using, and so can predict its
capabilities.
Does it limit the code to IE?
There are no scriptable web browser environments where a property of the
global object with the name - window - does not refer to the global
object, and so no scriptable web browser environments where the body of
the - if - statement will not be executed. And non-web browser
environments do not provide facilities for executing javascript
pseudo-protocol URLs.
* full void wrap - you mean instead of the final void(0), right?
<snip>
VK has a strong, and apparently unshakable, belief in the magical powers
of the javascript - void - operator. As an operator - void - forms part
of an expression, it evaluates its right hand side operand (forcing any
consequential side-effects to happen) and then ensures that the
expression it forms results in the undefined value.
So in your - void(0) - expression the right hand side operand is the
grouped expression - (0) - which evaluates as the number zero, but the
entire expression evaluates as the undefined value.
An expression representing a call to any function (technically, a
CallExpression) evaluates as the value returned from the function call.
If the body of a function is exited via a return statement and that
return statement specifies a value to be returned then it is that value
that becomes the value of the entire CallExpression.
In javascript all expressions must evaluate to a value or a Reference,
and so all CallExpressions must evaluate to a value or a Reference, but
not all functions include a return statement, and not all return
statements return explicit values. Javascript reconciles this requirement
for function calls to always result in value by providing a default value
whenever a a call to a function does not explicitly return a value
itself. All function calls that do not explicitly end at a return
statement that returns a value actually return the undefined value
instead.
The anonymous function called inline (- (function(){ ... })() -) does not
include a return statement and so it returns undefined. As a result the
value of the CallExpression is also the undefined value. So using the
CallExpression as the operand of the - void - operator is evaluating the
CallExpression to get the undefined vlaue and then evaluating the -
void - expression to the undefined value:-
void (function(){ ... })())
-where the anonymous function expression does not include any return
statement, has the same value as:-
(function(){ ... })())
- and so will have the same result in any context in which it is used.
Using - void - in that context is just another mystical incantation.
Useless, but again harmless enough not to be weeded out by those not
knowledgeable enough to see its uselessness.
Richard.