Is there a way to avoid eval in this block of js?
// Check requirements Prototype and Scriptaculous
(function () {
var requires = [
'Prototype'
, 'Scriptaculous'
]
while (r = requires.pop()) {
if (eval('typeof ' + r + ' == "undefined"')) alert(r + ' is required');
}
} ());
The eval here is completely pointless:
// since everything in the global scope gets defined on 'window'
typeof window[r] === 'undefined';
This will do the exact same thing, also note that r leaks into the global scope.
// Check requirements Prototype and Scriptaculous
(function () {
var requires = ['Prototype', 'Scriptaculous'];
var r = ''; // make sure to __not__ override a global r
while (r = requires.pop()) {
if (typeof window[r] === 'undefined') {
alert(r + ' is required');
}
}
} ());
How about
if (typeof window[r] == "undefined")
while (r = requires.pop()) {
if (typeof window[r] == "undefined") alert(r + ' is required');
}
Related
tem.jqw.Callback object contains an executable function, a CSS selector. and a looping delay.
tem.jqw.wait waits for jQuery to be loaded and then goes through an array of tem.jqw.Callback objects and executes their functions after having found an element with the CSS selector passed in.
The problem I am having is in the run function within the tem.jqw.Callback object. When the run function is called the first time, if the element exists, everything is fine and the executable function runs OK. However, if the element does not yet exist, and we need to loop, the function loses scope after setTimeout(this.run, 100) executes once. For example, when the run function is executing the second time, this.selector or this.fn become undefined. How can I work around this without using global variables? Thanks in advance.
if (typeof tem !== "object") {
tem = {};
}
tem.jqw = {};
tem.jqw.retries = 0;
tem.jqw.maxRetries = 100;
tem.jqw.delay = 100;
tem.jqw.callbacks = [];
tem.jqw.Callback = function (fn, selector, delay) {
this.fn = fn;
this.selector = (typeof selector === "string" && selector.length > 0) ? selector : document;
this.delay = (typeof delay === "number" && delay > 0 && delay < 1000) ? delay : 100;
this.retries = 0;
this.maxRetries = 100;
this.start = function () {
this.run();
};
this.run = function () {
if (jQuery(this.selector).length > 0) {
console.log("[OPDEBUG] tem.jqw.Callback.run says: " + this.selector.toString() + " is ready. Executing callback function...");
this.fn();
} else {
this.retries++;
console.log("[OPDEBUG] tem.jqw.Callback.run says: typeof this.selector " + typeof this.selector);
console.log("[OPDEBUG] tem.jqw.Callback.run says: Waiting for " + this.selector.toString() + "...");
if (this.retries < this.maxRetries) {
setTimeout(this.run, 100);
}
}
};
};
tem.jqw.wait = function () {
if (typeof jQuery === "function") {
console.log("[OPDEBUG] tem.jqw.wait says: jQuery is ready.");
for (var i = 0; i < tem.jqw.callbacks.length; i++) {
if (typeof tem.jqw.callbacks[i] === "object" && typeof tem.jqw.callbacks[i].start === "function") {
console.log("[OPDEBUG] tem.jqw.wait says: Executing callback function " + (i + 1) + "...");
tem.jqw.callbacks[i].start();
}
}
} else {
tem.jqw.retries++;
console.log("[OPDEBUG] tem.jqw.wait says: " + "Waiting for jQuery " + tem.jqw.retries + "...");
if (tem.jqw.retries < tem.jqw.maxRetries) {
setTimeout(tem.jqw.wait, tem.jqw.delay);
}
}
};
tem.jqw.callbacks.push(new tem.jqw.Callback(function () {
jQuery('.hero-inner:first a').css('background-image', 'url("https://www.thedogs.co.nz/Files/PhotoFinishImages/11298_89160.jpg")')
}, ".hero-inner:first"));
tem.jqw.callbacks.push(new tem.jqw.Callback(function () {
jQuery('.RR-placeholder ul li:first').hide();
}, ".RR-placeholder ul li:first"));
tem.jqw.wait();
you can use bind to set this
change this.run() to
this.run.bind(this)
Its better to assign this to another variable eg)
var self = this;
and then pass around self for better readability
One must check Obj.key1, Obj.key2, ..., Obj.key(n-1) if they're undefined.
The normal convention would be:
if (typeof Obj !== 'undefined') {
if (typeof Obj.key1 !== 'undefined') {
if (typeof Obj.key1.key2 !== 'undefined')
...
if (typeof Obj.key1.key2...keyN !== 'undefined') {
return Obj.key1.key2...keyN
}
...
}
}
}
Normally that code is shortened a bit into
if (obj && obj.key1 && obj.key1.key2 && obj.key1.key2.key3) {
return obj.key1.key2.key3.key4;
}
because undefined is also falsy and any object is instead truthy.
The shorter but IMO logically uglier alternative is
try { return obj.key1.key2.key3.key4; } catch(e) { }
that may be is acceptable if you never use Javascript properties as it can hide errors in non-trivial accessors.
var x;
try {
x = Obj.key1.key2.key3.key4....keyN;
}
catch(err) {
console.warn( err );
}
I normally use this piece of code, I call it resolve property.
function resolveProperty(object, property, deep) {
if(typeof deep === 'undefined') {
deep = true;
}
if(typeof property === 'string' && deep) {
property = property.split('.');
}
if(!object) {
return null;
}
if(!deep) {
property = Array.isArray(property) ? property[0] : property;
if(typeof property === 'undefined') {
return object;
} else {
return object[property];
}
}
return resolveProperty(object[property.shift()], property, property.length > 1);
}
$('#results').append(' > ' + resolveProperty({ a: {}}, 'a.b') + '<br />');
$('#results').append(' > ' + resolveProperty({ a: {}}, 'a.b.c.d') + '<br />');
$('#results').append(' > ' + resolveProperty({ a: { b: 1 }}, 'a.b') + '<br />');
$('#results').append(' > ' + resolveProperty({ a: { b: 1 }}, 'a.b.c') + '<br />');
$('#results').append(' > ' + resolveProperty({ a: { b: { c: '123' } }}, 'a.b.c') + '<br />');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="results" />
It will actualy resolve the property so you can compare to undefined like
if(resolveProperty(yourObject, 'a.b.c.d.e')) {
//good to go
}
PS.: You might wanna replace the array verification method (Array.isArray) if you will run this code in the browser since it is not default (cross browser).
I don't necessarily recommend this solution, but you could do
function getPath(obj, path) {
return path.split(.).reduce(function(val, seg) {
return val && typeof val === 'object' && val[seg];
}, obj);
}
Now you can just do
getPath(Obj, 'key1.key2.key3...keyN')
If you are a CoffeeScript user, you can use the so-called "existential operator":
Obj.key1?.key2?.key3?...keyN
I have a new AngularJS project I've just set up. I've installed angular and angular-resource via bower and all's good. I've installed another service I've used before - https://github.com/Fundoo-Solutions/angularjs-modal-service but when I inject the module it causes the error below:
Uncaught object
It's pointing to the return statement of this function in AngularJS:
function minErr(module) {
return function () {
var code = arguments[0],
prefix = '[' + (module ? module + ':' : '') + code + '] ',
template = arguments[1],
templateArgs = arguments,
stringify = function (obj) {
if (typeof obj === 'function') {
return obj.toString().replace(/ \{[\s\S]*$/, '');
} else if (typeof obj === 'undefined') {
return 'undefined';
} else if (typeof obj !== 'string') {
return JSON.stringify(obj);
}
return obj;
},
message, i;
message = prefix + template.replace(/\{\d+\}/g, function (match) {
var index = +match.slice(1, -1), arg;
if (index + 2 < templateArgs.length) {
arg = templateArgs[index + 2];
if (typeof arg === 'function') {
return arg.toString().replace(/ ?\{[\s\S]*$/, '');
} else if (typeof arg === 'undefined') {
return 'undefined';
} else if (typeof arg !== 'string') {
return toJson(arg);
}
return arg;
}
return match;
});
message = message + '\nhttp://errors.angularjs.org/1.2.18/' +
(module ? module + '/' : '') + code;
for (i = 2; i < arguments.length; i++) {
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
encodeURIComponent(stringify(arguments[i]));
}
return new Error(message);
};
}
I think it's saying that Error doesn't exist?
Am I missing a module or something?
One of the reason why a person get this error with Angular. The module that you have included is not injected properly. For example, you must inject it as a Dependency injection properly before using that. So, please make sure that it's done.
And another reason is properly define ng-app="<app-name>" and make sure that the file in which you have written your Angular application code, for example: angular.module('<app-name>', []) is included as the script file.
I use this small class function for my javascript code; actually it is somehow altered in the way it 'implements' other classes so that it 'inherets' only functions and not properties (see it at: https://github.com/centurianii/g3OO).
The problem is that it:
1) doesn't give a <object>.constructor.name, see No.3 and 4 at http://jsfiddle.net/A8SkN/3/ (eventually what I want is somehow to have the name of the new class which is stored in a variable-I know it's a complete madness compared with proper OO languages) and
2) doesn't pass any specific static property with name name (but it sees everything else as long as it has a different name!), see No.6 at jsfiddle above.
Here is the Class code:
(function(window, document, undefined){
// Namespace object
var g3;
// Return as AMD module or attach to head object
if (typeof define !== 'undefined')
define([], function () {
g3 = g3 || {};
return g3;
});
else if (typeof window !== 'undefined')
g3 = window.g3 = window.g3 || {};
else{
g3 = g3 || {};
module.exports = g3;
}
g3.Class = function () {
var len = arguments.length;
if(len === 0 || (len === 1 && arguments[0] === null))
return function() {};
var body = arguments[len - 1],
SuperClass = len > 1 ? arguments[0] : null,
implementClasses = len > 2,
Class,
SuperClassEmpty,
i;
//we expect last object to override 'constructor' otherwise the new is empty!
if (body.constructor === Object) {
Class = function() {};
} else {
Class = body.constructor;
delete body.constructor;
}
//'Class.Super' is a reserved word for g3.Class!
if (SuperClass) {
SuperClassEmpty = function() {};
SuperClassEmpty.prototype = SuperClass.prototype;
Class.prototype = new SuperClassEmpty();
Class.prototype.constructor = Class;
//doesn't work!
//Class.prototype.constructor.name = Class.prototype.toString();
Class.Super = SuperClass;
extend(Class, SuperClass, false); //works for static members!
}
if (implementClasses)
for (i = 1; i < len - 1; i++)
if(typeof arguments[i] === 'object')
extend(Class.prototype, arguments[i], false, 'function');
else
extend(Class.prototype, arguments[i].prototype, false);
extendClass(Class, body);
return Class;
};
function extendClass(Class, extension, override) {
//'STATIC' is a reserved word from last argument of g3.Class!
if (extension.STATIC) {
extend(Class, extension.STATIC, override); //overwrites previous parent's static members
delete extension.STATIC;
}
extend(Class.prototype, extension, override);
};
var extend = g3.Class.extend = function (obj, extension, override, type) {
var prop;
if (override === false) {
for (prop in extension)
if (!(prop in obj))
if(!type)
obj[prop] = extension[prop];
else if(typeof extension[prop] === type)
obj[prop] = extension[prop];
} else {
for (prop in extension)
if(!type)
obj[prop] = extension[prop];
else if(typeof extension[prop] === type)
obj[prop] = extension[prop];
if (extension.toString !== Object.prototype.toString)
obj.toString = extension.toString;
}
};
}(window, document));
Let's test Class:
///////TESTS///////
function Person(name){
this.name = name;
}
//Class Dreamer extends Person
var Dreamer = g3.Class(Person, {
STATIC: {
dreams: [],
name: 'Dreamer'
},
constructor: function(name, dream) {
//Explicit call to Dreamer.Super === Person
Dreamer.Super.call(this, name);
this.dream = dream;
},
add: function() {
Dreamer.dreams.push(this.dream);
},
toString: function(){
return 'Dreamer';
}
});
var poet = new Dreamer('Hary', 'I\'ll write a poem today!');
poet.add();
/////PRINT/////
var tests = '<ol><li>poet.toString() = ' + poet.toString() + '</li>';
tests += '<li>poet.constructor = ' + poet.constructor + '</li>';
tests += '<li>poet.constructor.name = ' + poet.constructor.name + '</li>';
tests += '<li>poet.constructor.name == \'\' : ' + (poet.constructor.name === '')+ '</li>';
tests += '<li>poet.prototype = ' + poet.prototype + '</li>';
if(poet.prototype)
tests += '<li>poet.prototype.constructor = ' + poet.prototype.constructor + '</li>';
tests += '<li>Dreamer.name = ' + Dreamer.name + '</li>';
tests += '<li>Dreamer.dreams = ' + Dreamer.dreams + '</li>';
document.getElementById('class').innerHTML = tests + '</ol>';
The results:
1. poet.toString() = Dreamer
2. poet.constructor = function (name, dream)...
3. poet.constructor.name =
4. poet.constructor.name == '' : true //empty string!
5. poet.prototype = undefined
6. Dreamer.name = //empty string!
7. Dreamer.dreams = I'll write a poem today!
Any ideas?
Thanks.
Dart, Google's new web language, says it supports outputting to JavaScript.
What does a simple conversion look like?
main() {
print('Hello, Dart!');
}
When compiled with dart2js (as of 2013-04-26) (see note at bottom) it is converted into:
// Generated by dart2js, the Dart to JavaScript compiler.
// The code supports the following hooks:
// dartPrint(message) - if this function is defined it is called
// instead of the Dart [print] method.
// dartMainRunner(main) - if this function is defined, the Dart [main]
// method will not be invoked directly.
// Instead, a closure that will invoke [main] is
// passed to [dartMainRunner].
function Isolate() {}
init();
var $ = Isolate.$isolateProperties;
// Bound closures
$.Primitives_printString = function(string) {
if (typeof dartPrint == "function") {
dartPrint(string);
return;
}
if (typeof window == "object") {
if (typeof console == "object")
console.log(string);
return;
}
if (typeof print == "function") {
print(string);
return;
}
throw "Unable to print message: " + String(string);
};
$.main = function() {
$.Primitives_printString("Hello, Dart!");
};
$.String = {builtin$cls: "String"};
var $ = null;
Isolate = Isolate.$finishIsolateConstructor(Isolate);
var $ = new Isolate();
// BEGIN invoke [main].
if (typeof document !== "undefined" && document.readyState !== "complete") {
document.addEventListener("readystatechange", function () {
if (document.readyState == "complete") {
if (typeof dartMainRunner === "function") {
dartMainRunner(function() { $.main(); });
} else {
$.main();
}
}
}, false);
} else {
if (typeof dartMainRunner === "function") {
dartMainRunner(function() { $.main(); });
} else {
$.main();
}
}
// END invoke [main].
function init() {
Isolate.$isolateProperties = {};
Isolate.$finishIsolateConstructor = function(oldIsolate) {
var isolateProperties = oldIsolate.$isolateProperties;
isolateProperties.$currentScript = typeof document == "object" ? document.currentScript || document.scripts[document.scripts.length - 1] : null;
var isolatePrototype = oldIsolate.prototype;
var str = "{\n";
str += "var properties = Isolate.$isolateProperties;\n";
var hasOwnProperty = Object.prototype.hasOwnProperty;
for (var staticName in isolateProperties) {
if (hasOwnProperty.call(isolateProperties, staticName)) {
str += "this." + staticName + "= properties." + staticName + ";\n";
}
}
str += "}\n";
var newIsolate = new Function(str);
newIsolate.prototype = isolatePrototype;
isolatePrototype.constructor = newIsolate;
newIsolate.$isolateProperties = isolateProperties;
return newIsolate;
};
}
//# sourceMappingURL=out.js.map
Note for posterity: The original answer to this question has been modified to reflect the current state of affairs.
On 2012-05-12 the dart output for Hello World was 18,718 characters.
On 2012-08-29 the output was 1531 characters.
On 2013-04-26, the output was 2642 characters.
dart2js can minify code. Here is an example (as of 2013-04-26)
// Generated by dart2js, the Dart to JavaScript compiler.
function I(){}
init()
var $=I.p
$.ib=function(a){if(typeof dartPrint=="function"){dartPrint(a)
return}if(typeof window=="object"){if(typeof console=="object")console.log(a)
return}if(typeof print=="function"){print(a)
return}throw "Unable to print message: " + String(a)}
$.E2=function(){$.ib("Hello, Dart!")}
$.qU={builtin$cls:"qU"}
var $=null
I = I.$finishIsolateConstructor(I)
var $=new I()
if (typeof document !== "undefined" && document.readyState !== "complete") {
document.addEventListener("readystatechange", function () {
if (document.readyState == "complete") {
if (typeof dartMainRunner === "function") {
dartMainRunner(function() { $.E2(); });
} else {
$.E2();
}
}
}, false);
} else {
if (typeof dartMainRunner === "function") {
dartMainRunner(function() { $.E2(); });
} else {
$.E2();
}
}
function init(){I.p={}
I.$finishIsolateConstructor=function(a){var z=a.p
z.$currentScript=typeof document=="object"?document.currentScript||document.scripts[document.scripts.length-1]:null
var y=a.prototype
var x="{\n"
x+="var properties = I.p;\n"
var w=Object.prototype.hasOwnProperty
for(var v in z){if(w.call(z,v)){x+="this."+v+"= properties."+v+";\n"}}x+="}\n"
var u=new Function(x)
u.prototype=y
y.constructor=u
u.p=z
return u}}//# sourceMappingURL=out.js.map
On 2013-04-26, the minified code was 1386 characters.
The output of the Dart->JavaScript compiler is a moving target. The first release (technical preview) didn't do a lot of tree shaking and was thus pretty big.
The new (experimental) frog compiler is much better in this respect (David Chandler's blog), but I expect DartC to improve considerably too.