I have the following dart code:
$ cat helloworld.dart
main() => print('Hello world!');
$
The javascript code generated by the dart compiler for the above code is as follows:
$ cat helloworld.dart.app.js
function native_ListFactory__new(typeToken, length) {
return RTT.setTypeInfo(
new Array(length),
Array.$lookupRTT(RTT.getTypeInfo(typeToken).typeArgs));
}
function native_ListImplementation__indexOperator(index) {
return this[index];
}
function native_ListImplementation__indexAssignOperator(index, value) {
this[index] = value;
}
function native_ListImplementation_get$length() {
return this.length;
}
function native_ListImplementation__setLength(length) {
this.length = length;
}
function native_ListImplementation__add(element) {
this.push(element);
}
function native_BoolImplementation_EQ(other) {
return typeof other == 'boolean' && this == other;
}
function native_BoolImplementation_toString() {
return this.toString();
}
<snapped>
var static$uninitialized = {};
var static$initializing = {};
function $inherits(child, parent) {
if (child.prototype.__proto__) {
child.prototype.__proto__ = parent.prototype;
} else {
function tmp() {};
tmp.prototype = parent.prototype;
child.prototype = new tmp();
child.prototype.constructor = child;
}
}
isolate$inits.push(function(){
isolate$current.Duration$DartMILLISECONDS_PER_MINUTE$field = static$uninitialized;
isolate$current.Duration$DartMILLISECONDS_PER_HOUR$field = static$uninitialized;
isolate$current.Duration$DartMILLISECONDS_PER_DAY$field = static$uninitialized;
isolate$current.Duration$DartSECONDS_PER_HOUR$field = static$uninitialized;
isolate$current.Duration$DartSECONDS_PER_DAY$field = static$uninitialized;
isolate$current.Duration$DartMINUTES_PER_DAY$field = static$uninitialized;
}
);
RunEntry(unnamedd9297f$main$member, this.arguments ? (this.arguments.slice ? [].concat(this.arguments.slice()) : this.arguments) : []);
$
And the size of helloworld.dart.app.js is 102k!
When ran in optimize mode, it generated the following javascript - helloworld.dart.js which is of size 20k
$ cat helloworld.dart.js
var e;function f(a,b){if(b>=0&&b<a.length)return b;h(i(b))};var j={},k={};function aa(a,b,c){if(b)a.g=function(){return b.call(c)}}function ba(a,b,c,d){function g(b,g,t,m){return a.call(c,d,b,g,t,m)}aa(g,b,c);return g}function l(a,b){if(a.prototype.__proto__)a.prototype.__proto__=b.prototype;else{var c=function(){};c.prototype=b.prototype;a.prototype=new c;a.prototype.constructor=a}}function ca(a,b){return typeof a=="number"&&typeof b=="number"?a+b:a.na(b)}function da(a){a/=4;return a<0?Math.ceil(a):Math.floor(a)}
function o(a,b){if(a===void 0)return b===void 0;else if(typeof a==typeof b&&typeof a!="object")return a===b;return a.G(b)}function h(a){a&&typeof a=="object"&&Error.captureStackTrace&&Error.captureStackTrace(a);throw a;}function p(){var a=new q;a.f=s("ya",ea);a.va="";a.qa="";a.N=[];h(a)}var u={d:0};
<snapped>
y.push(function(){x.fb=j;x.eb=j;x.gb=j});y.push(function(){x.Ta=j;x.Sa=j;x.Ra=j;x.Wa=j;x.Va=j;x.Ua=j});(function(a,b){if(!A){var c=new ya;oa=c;sa(c,function(){a(b)});Ea();x=c}})(function(){return qb()(1,u,"Hello world!")},this.arguments?this.arguments.slice?[].concat(this.arguments.slice()):this.arguments:[]);
$
Why is the javascript code which was generated by a dart compiler so huge?
What problem are they trying to solve by generating such huge javascript files?
Side Note: The javascript files were so huge, SO threw the following error:
Oops! Your question couldn't be submitted because: body is limited to 30000 characters; you entered 140984
What problem are they trying to solve by generating such huge javascript files?
The problem of balancing Dart to be optimal in the majority of cases, rather than just this one personal, specific, contrived, useless example program that nobody would ever seriously try to use in a production project.
If you would like to get even a better JavaScript, try the Frog compiler instead of DartC. Frog ist written in Dart itself.
http://turbomanage.wordpress.com/2011/12/09/dart-dev-mode-cometh/
Note, this blogpost above is a bit outdated. You can meanwhile use the Dart SDK for Frog:
http://gsdview.appspot.com/dart-editor-archive-continuous/3058/
This post might also be of interest for you, Seth shows how the Frog generated JS looks like:
http://blog.sethladd.com/2011/12/10-lessons-from-porting-javascript-to.html
Here is how you can enable Frog in current Editor:
https://groups.google.com/a/dartlang.org/group/misc/msg/5dfe04c69ed0fed3
Why is the javascript code which was generated from a dart code by a dart compiler is so huge?
Because it includes a Dart runtime.
What problem are they trying to solve by generating such huge javascript files?
The problem of running code that is not JavaScript in a browser.
Related
I am doing some research on a running website, and the behavior of the code just surprises me.
They defined a function named '__jsload' and bind it to window.
window._jsload = function(hJ, hK) {
var i = d2.getModuleInfo(hJ);
i.status = d2.Request.LOADED;
if (hK !== "") {
d2.run(hJ, hK)
} else {
if (window.map) {
var e = new a6("ongetmodules_fail");
e.moduleName = hJ;
window.map.fire(e)
}
var T = document.createElement("script");
var hI = d2.MD5Mapping[hJ];
T.src = d2.Config.jsModPath + hJ + "_" + hI + ".js";
document.getElementsByTagName("head")[0].appendChild(T)
}
};
In the run function, there's only an eval(), it seems nothing is stored for future use.
run: function(T, hI) {
var hM = this.getModuleInfo(T);
var hP = this.Dependency[T];
if (hP) {
for (var hK = 0; hK < hP.length; hK++) {
var hL = this.getModuleInfo(hP[hK]);
if (hL.status !== this.Request.COMPLETED) {
hL.modsNeedToRun.push({
name: T,
code: hI
});
return
}
}
}
try {
eval(hI)
} catch (hN) {
return
}
hM.status = this.Request.COMPLETED;
for (var hK = 0, hJ = hM.callbacks.length; hK < hJ; hK++) {
hM.callbacks[hK]()
}
hM.callbacks.length = 0;
for (hK = 0; hK < hM.modsNeedToRun.length; hK++) {
var hO = hM.modsNeedToRun[hK];
this.run(hO.name, hO.code)
}
hM.modsNeedToRun.length = 0
},
Then all the module are written in the following manner.
/**/_jsload&&_jsload(
// this should be the module name
'glcommon',
// this should be the module content
'function aO(e,i)......'
)
I have a little experience in coding in python, so I thought those loaded modules will be special objects, and I can access functions defined in the module by just calling them.
import pandas as pd
pd.DataFrame()
And I searched some references on coding in javascript, they mentioned something like 'import/export' and maybe 'require'. After importing the module, I can call exported function just by calling the name.
// in sayHi.js
export function sayHi(user) {
alert(`Hello, ${user}!`);
}
// in main.js
import {sayHi} from './sayHi.js';
alert(sayHi); // function...
sayHi('John'); // Hello, John!
None of these things happens in that website I'm researching on. There's even no 'export' in the whole module text.
So, here rises my question.
Is it possible to call the function in a module in the web console? If it's not bound to the window object, will it still be possible?
We all know that currently a lot of web pages are dynamic, when a certain event happens, a certain function relate to it should be called. So, where are those functions saved? Are they still reachable during the web is running?
3.How can I debug modules like the above ones, when you can't get a pretty printed version of code and make some breakpoints? I tried to go step by step, but all the functions go into the text versioned module, and I can't make a breakpoint.
I use the Refactor function of vscode to rename the variable name. I found that there is no problem with the smart modification of the global variable or the local variable, but the property of the object does not take effect. Is there any method or extension that can do this?
Vscode info:
Version: 1.36.1 (user setup)
Submit: 2213894ea0415ee8c85c5eea0d0ff81ecc191529
Date: 2019-07-08T22:59:35.033Z
Electron: 4.2.5
Chrome: 69.0.3497.128
Node.js: 10.11.0
V8: 6.9.427.31-electron.0
OS: Windows_NT x64 10.0.18922
g = se.prototype;
g.eb = function (a) {
this.pf = this.Sr(); //this.Sr will be refactored
a = this.cu(a);
return Pc(a, null)
};
g.au = function (a) {
this.pf && "*" == this.Me && (a.id = this.pf)
};
g.Tt = function (a) {
if (!this.zi)
return a;
a = de("<div>" + a + "</div>");
he(a);
return a.innerHTML
};
g.Sr = function () { //want to smart rename the g.Sr to g.sanitizer
var a = !("STYLE" in this.Pe) && "STYLE" in this.Qe;
return "*" == this.Me && a ? "sanitizer-" + (Math.floor(2147483648 * Math.random()).toString(36) + Math.abs(Math.floor(2147483648 * Math.random()) ^ Ja()).toString(36)) : this.Me
};
VS Code's built-in JavaScript IntelliSense is not able to understand that code, which is why rename does not work. The code relies a lot on dynamic behavior such as assigning g to se.prototype and then further writing properties on to g. The IntelliSense engine just can't understand that this.Sr inside eb refers to the same g.Sr below (it's also not obvious what is going on to a programmer at first glance either)
You can investigate this by hovering over various variables in your source. If the hover information shows any, it means that the VS Code IntelliSense engine cannot properly infer what type the variable is so semantic operations like rename will not work. You can also add // #ts-check to the top of your file to enable some basic type checking of your code
For the existing snippet however, your best bet is to do a text based find/replace.
By OO I mean classical OO. I keep going back and forth between defining my "classes" ( javascript does not have traditional classes ) using the module pattern to provide privacy and using object literals to create a collection of "public statics".
I have no guiding force when I create "classes" that lets me determine what type of organization to use. Well, besides the fact that my code passes both jshint and jslint w/ no options set.
I'm working w/ about 1500 lines of code so I need a "guiding force" before the code becomes un-manageable and I have to scrap it.
I am well aware of the different ways to write "classes" in JavaScript. Those taught by JavaScript Web Applications written by Alex MacCaw as well as the numerous ways listed here on SO.
However, application wise, I just don't know what method to use.
The simplest seems to be a collection of methods and variables in an object literal like this:
var public_statics = {
public_func: function () {},
public_var: "hello"
}
and the most complicated seems to be - an IIFE.
(function(){
var private_var;
function private_func(){
}
})();
How do I know which one to use or the multitude of in-between variations?
For a concrete example: How about for a controller in the MVC.
Currently ( and some what randomly chosen), I implement a controller like this:
var Co = {};
Co.Controller = function(){
// 'classes' from Mo are called here
// 'classes' from Su are called here
}
then I tack on other Control related method to Co.
How do I choose what style of OO to use?
Updated
My library is currently divided between 4 namespaces:
var Mo = {},
Vi = {},
Co = {},
Su = {};
Model, View, and Controller should be self-explanatory and (Su)pport is for all "classes" not contained in the MVC, for example DOM access, Effects, Debug code, etc.
What OO style should I use to further organize this library/code?
Controller "Class" example:
/**
** Controller
*/
Co.Controller = function (o_p) {
var o_p_string_send;
Su.time();
o_p = Mo[o_p.model].pre(o_p);
if (o_p.result !== 'complete') {
o_p_string_send = JSON.stringify(o_p);
Su.time();
//Su.log(o_p_string_send);
Co.serverCall('pipe=' + o_p_string_send, function (o_p_string_receive) {
Su.time();
//Su.log(o_p_string_receive);
o_p.server = JSON.parse(o_p_string_receive);
Mo[o_p.model].post(o_p);
Su.time(true);
Su.log('Server time: [' + o_p.server.time + ']');
});
}
};
IFFEs are often confusing to read and personally, I have no idea why they have become so mainstream. I think code should be easy to read and concise. Attempting to simulate language behavior that is not part of the language specification is often-times a very dumb idea.
For example, JavaScript does not support multiple inheritance, polymorphism, or many other interesting paradigms. So a lot of times, we see people trying to create these crazy ways of sorta'-kinda' having polymorphism or private members, etc in JS. I think this is a mistake.
I'm currently working as a sort of hobby project on a high-performance JS data structures library (I'm trying to outperform Google's closure and a bunch of others). Coming from a C++ and Java background, I always like to make stuff classes and I like inheritance, etc, etc. Let me share some code-snippets with you. At first, I thought I was being clever because I was writing stuff like this:
function __namespace(n, v) {
return {"meta":{"namespace":n,"version":v}};
}
var FJSL = FJSL == undefined ? new __namespace("Fast JavaScript Library", 0.1) : FJSL;
__using = function(parent, child) {
clazz = new child();
clazz.super = new parent();
if (clazz.super == undefined) return clazz;
for (a in clazz.super) {
for (b in clazz) {
if (a == "constructor" || b == "constructor") continue;
if (clazz[b] === clazz.super[a]) continue;
if (a == b && typeof clazz[b] != typeof clazz.super[a]) throw "Typesafety breached on '" + a + "' while trying to resolve polymorphic properties.";
if (a == b && typeof clazz[b] == typeof clazz.super[a]) {
clazz["_"+a] = clazz.super[a];
} else if (clazz[a] == undefined) {
clazz[a] = clazz.super[a];
}
}
}
return clazz;
};
And I was using it like so (in the example of a simple Queue):
FJSL.Array = function() {
this.data = [];
this.contains = function(idx, element) {
for (var i = idx; i < this.data.length; i++) {
if (this.data[i] === element)
return i;
}
return -1;
}
this.size = function() {
return this.data.length;
}
}
FJSL.Queue = function() {
return __using(FJSL.Array,
function() {
this.head = 0;
this.tail = 0;
this.enqueue = function(element) {
this.data[this.tail++] = element;
};
this.dequeue = function() {
if (this.tail == this.head)
return undefined;
return this.data[this.head++];
};
this.peek = function() {
return this.data[this.head];
};
this.size = function() {
return this.tail - this.head;
};
this.contains = function(element) {
return this._contains(this.head, element);
};
}
)};
You'll note how I'm sort of faking inheritance (a Queue uses an Array, har har, I'm clever). However, this is absolutely insane to a) read and b) understand. I couldn't help but be reminded of this meme:
Let me show you functionally equivalent code without me trying to do all this fancy pre- and post-processing:
FJSL.Queue = function(opts) {
this.options = opts;
this.head = 0;
this.tail = 0;
this.data = [];
};
FJSL.Queue.prototype = {
add : function(element) {
this.data[this.tail++] = element;
},
enqueue : function(element) {
this.data[this.tail++] = element;
},
dequeue : function() {
if (this.tail == this.head) {
return undefined;
}
return this.data[this.head++];
},
peek : function() {
return this.data[this.head];
},
size : function() {
return this.tail - this.head;
},
contains : function(element) {
// XXX: for some reason a for : loop doesn't get JIT'ed in Chrome
for (var i = this.head; i < this.data.length; i++) {
if (this.data[i] === element) {
return true;
}
}
return false;
},
isEmpty : function() {
if (size) {
return true;
}
return false
},
clear : function() {
this.data = [];
}
};
Obviously, I'd have to duplicate the prototype constructor for any other structures that may use an array, but what I'm trying to accomplish is so much clearer, even a novice JS programmer can tell what's going on. Not only that, but if people want to modify the code, they know exactly where to go and what to do.
My suggestion is don't get caught up in the insanity of trying to make JS behave like C++ or Java. It's never going to. And yeah, you can fake inheritance and private/public/protected members, but JS was never intended for that. I think the repercussion of having this kind of bloated code (that attempts to simulate non-standard behavior) is very taxing on high-performance web-apps and their ilk.
In short, I suggest using an object literal:
var public_statics = {
public_func: function () {},
public_var: "hello"
}
It's easy to understand, easy to modify, and easy to extend. If your system is brittle enough to crash and burn if someone accidentally changes some "private" variable, you simply need to document it.
I personally prefer the IIFE simply because you can make methods private. Otherwise, you will have to do some sort of weird convention with underscores.
Furthermore, stylitically, if you encapsulate it within a function, you have the option of making semicolons - its plain old javascript. Requiring each line in the object literal to end with a comma seems funny to me.
Because JavaScript the language itself is implemented in many different ways, i.e. it is different for each browser, you already have to begin with inconsistency.
JavaScript does not directly support classical inheritance. ( It supports prototypical inheritance ).
For my needs I will choose not to implement classical inheritance. This is not ideal b.c. classical inheritance allows you to directly implement best practice OO - encapsulation, inheritance, and polymorphism.
However I prefer to wait until the language directly supports OO via classical inheritance or similar.
In the mean time I will just use the basic prototypical inheritance to help enable code re-use.
I was tearing my hair out to get this done...particularly for an html5 detection script. I wanted a variable that is set only once and that can't be overwritten again. This is it:
var StaticConfiguration = {};
StaticConfiguration.Main = {
_html5: null
}
StaticConfiguration.getVariable = function(name) {
return StaticConfiguration.Main["_" + name];
}
StaticConfiguration.setVariable = function(name, value) {
if(StaticConfiguration.Main["_" + name] == null) {
StaticConfiguration.Main["_" + name] = value;
}
}
First, I define a global object StaticConfiguration containing all of these variables - in my case, just "html5". I set it to null, since I want to set it inside the application. To do so, I call
StaticConfiguration.setVariable("html5", "true");
It's set then. If I try to set it again, it fails - of course, since _html5 is not null anymore. So I practically use the underscore to "hide" the static variable.
This is helping me a lot. I hope it's a good approach - please tell me if not :)
First off, it's true, not "true" all strings (apart from the empty string) evaluate to true, including the string "false".
Second off, do you really need to protect data like this? There's not really any way to safely run a user's Javascript i your context anyway. There's always a way around protection like this. If offending code really cared, it could just replace the whole StaticConfiguration object anyway.
Matthew's code is a better approach to the problem, but it doesn't follow a singleton pattern, but is a class that needs to be instanciated. I'd do it more like this, if you wanted a single object with "static" variables.
StaticConfiguration = new (function()
{
var data = {}
this.setVariable = function(key, value)
{
if(typeof data[key] == 'undefined')
{
data[key] = value;
}
else
{
// Maybe a little error handling too...
throw new Error("Can't set static variable that's already defined!");
}
};
this.getVariable = function(key)
{
if (typeof data[key] == 'undefined')
{
// Maybe a little error handling too...
throw new Error("Can't get static variable that isn't defined!");
}
else
{
return data[key];
}
};
})();
Personal sidenote: I hate the "curly brackets on their own lines" formatting with a passion!
Take a look at Crockford's article on Private Members in JavaScript. You can do something like this:
var StaticConfiguration = (function() {
var html5; /* this is private, i.e. not visible outside this anonymous function */
return {
getVariable: function(name) {
...
},
setVariable: function(name, value) {
...
}
};
)();
How about:
var StaticConfiguration = new (function()
{
var data = {}
this.setVariable = function(key, value)
{
if(typeof data[key] == 'undefined')
{
data[key] = value;
}
};
this.getVariable = function(key)
{
return data[key];
};
})();
Similar to the other answer, but still allows arbitrary keys. This is truly private, unlike the underscore solution.
I'm a little curious as to why you think that you have to go to this extent to protect the data from being overwritten. If you're detecting the browser, shouldn't it only be done once? If someone's overwriting it with invalid data, then I would assume that it would be a problem in the client implementation and not the library code - does that make sense?
As a side note, I'm pretty big on the KISS principle, especially when it comes to client side scripting.
I know i'm a little late to the party but in situations like this i usually
var data;
if (data === undefined || //or some other value you expect it to start with{
data = "new static value"
};
Long story short: I'm in a situation where I'd like a PHP-style getter, but in JavaScript.
My JavaScript is running in Firefox only, so Mozilla specific JS is OK by me.
The only way I can find to make a JS getter requires specifying its name, but I'd like to define a getter for all possible names. I'm not sure if this is possible, but I'd very much like to know.
Proxy can do it! I'm so happy this exists!! An answer is given here: Is there a javascript equivalent of python's __getattr__ method? . To rephrase in my own words:
var x = new Proxy({}, {
get(target, name) {
return "Its hilarious you think I have " + name
}
})
console.log(x.hair) // logs: "Its hilarious you think I have hair"
Proxy for the win! Check out the MDN docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
Works in chrome, firefox, and node.js. Downsides: doesn't work in IE - freakin IE. Soon.
You can combine proxy and class to have a nice looking code like php:
class Magic {
constructor () {
return new Proxy(this, this);
}
get (target, prop) {
return this[prop] || 'MAGIC';
}
}
this binds to the handler, so you can use this instead of target.
Note: unlike PHP, proxy handles all prop access.
let magic = new Magic();
magic.foo = 'NOT MAGIC';
console.log(magic.foo); // NOT MAGIC
console.log(magic.bar); // MAGIC
You can check which browsers support proxy http://caniuse.com/#feat=proxy.
The closest you can find is __noSuchMethod__ (__noSuchMethod__ is deprecated), which is JavaScript's equivalent of PHP's __call().
Unfortunately, there's no equivalent of __get/__set, which is a shame, because with them we could have implemented __noSuchMethod__, but I don't yet see a way to implement properties (as in C#) using __noSuchMethod__.
var foo = {
__noSuchMethod__ : function(id, args) {
alert(id);
alert(args);
}
};
foo.bar(1, 2);
Javascript 1.5 does have getter/setter syntactic sugar. It's explained very well by John Resig here
It's not generic enough for web use, but certainly Firefox has them (also Rhino, if you ever want to use it on the server side).
If you really need an implementation that works, you could "cheat" your way arround by testing the second parameter against undefined, this also means you could use get to actually set parameter.
var foo = {
args: {},
__noSuchMethod__ : function(id, args) {
if(args === undefined) {
return this.args[id] === undefined ? this[id] : this.args[id]
}
if(this[id] === undefined) {
this.args[id] = args;
} else {
this[id] = args;
}
}
};
If you're looking for something like PHP's __get() function, I don't think Javascript provides any such construct.
The best I can think of doing is looping through the object's non-function members and then creating a corresponding "getXYZ()" function for each.
In dodgy pseudo-ish code:
for (o in this) {
if (this.hasOwnProperty(o)) {
this['get_' + o] = function() {
// return this.o -- but you'll need to create a closure to
// keep the correct reference to "o"
};
}
}
I ended up using a nickfs' answer to construct my own solution. My solution will automatically create get_{propname} and set_{propname} functions for all properties. It does check if the function already exists before adding them. This allows you to override the default get or set method with our own implementation without the risk of it getting overwritten.
for (o in this) {
if (this.hasOwnProperty(o)) {
var creategetter = (typeof this['get_' + o] !== 'function');
var createsetter = (typeof this['set_' + o] !== 'function');
(function () {
var propname = o;
if (creategetter) {
self['get_' + propname] = function () {
return self[propname];
};
}
if (createsetter) {
self['set_' + propname] = function (val) {
self[propname] = val;
};
}
})();
}
}
This is not exactly an answer to the original question, however this and this questions are closed and redirect here, so here I am. I hope I can help some other JS newbie that lands here as I did.
Coming from Python, what I was looking for was an equivalent of obj.__getattr__(key)and obj.__hasattr__(key) methods. What I ended up using is:
obj[key] for getattr and obj.hasOwnProperty(key) for hasattr (doc).
It is possible to get a similar result simply by wrapping the object in a getter function:
const getProp = (key) => {
const dictionary = {
firstName: 'John',
lastName: 'Doe',
age: 42,
DEFAULT: 'there is no prop like this'
}
return (typeof dictionary[key] === 'undefined' ? dictionary.DEFAULT : dictionary[key]);
}
console.log(getProp('age')) // 42
console.log(getProp('Hello World')) // 'there is no prop like this'