2

First of all i know that:

Use of the with statement is not recommended, as it may be the source of confusing bugs and compatibility issues. See the "Ambiguity Con" paragraph in the "Description" section below for details.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with

BUT

If we take a simple function like this (THIS FUNCTION WORKS GREAT)

function loadImage(url,cb){
 with(new Image)
  onload=cb,
  src=url
}

we notice there is nothing CONFUSING that could break the code inside the function closures. the only 2 variables we use are onload & src. Until i don't create variables, objects,arrays or functions that i name onload or src nothing bad should happen.

Said that, my question is:

The javascript garbage collector should add the new Image to the collection directly after been executed ?

And so have less impact to the memory vs a standard function:

function loadImage(url,cb){
 var image=new Image;
 image.onload=cb;
 image.src=url;
}

In the above case the var image remains inside the function until i execute a new one. btw. also the code would be much shorter.

// preload a image
function loadImage(a,b){with(new Image)onload=b,src=a}

// convert a file to base64
function readFile(a,b){with(new FileReader)onload=b,readAsDataURL(a)}

A demo to play with

http://jsfiddle.net/5wqm3/4/

cocco
  • 16,442
  • 7
  • 62
  • 77
  • I'm curious *why* this implicit property assignment works as so with DOM elements (Chrome/FF at least); it does *not* work as so for normal JS objects. (And I can't recommend it because it is *not* consistent: `x = {}; with (x) { y = 2 }; x.y // => undefined; y // => 2`) – user2864740 Jun 04 '14 at 19:04
  • Also, "Using with is not recommended, and is forbidden in ECMAScript 5 strict mode" doesn't help the arguments in favor. – user2864740 Jun 04 '14 at 19:07
  • also i was totally affashinated about the fact that it works with dom elements and more. – cocco Jun 04 '14 at 19:08
  • i know that it does not work in strict mode ... i'm more concerned about the fact how not using 'var image=new Image()' has impact in the garbage collector. – cocco Jun 04 '14 at 19:09

1 Answers1

1

First of all i know that: Use of the with statement is not recommended, as it may be the source of confusing bugs and compatibility issues

No, the main issue with the with statement is that it prevents certain static optimisations as it introduces new variable names at runtime. That's also the reason why it was forbidden in ES 5 strict mode code.

Using the with statement should have less impact to the memory vs a standard function

No. They perform exactly the same. When the function ends, the new Image/image is no more in scope of anything. The image variable will be gone in the same way as the with statement ends with a closing brace.

The javascript garbage collector should add the new Image to the collection directly after been executed?

Actually, I don't think the object is garbage-collected. It's a DOM element with an alive load handler waiting for it, I would assume it is still referenced from the event loop queue. However, that doesn't really matter for your question I think.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • so theoretically the code has the same performance , memory impact but it's shorter? – cocco Jun 04 '14 at 19:51
  • if not using strict mode the with function is the better one if i want a short code? And reguarding the onload garbage collector i add a this.onload=null in the cb to break the references? – cocco Jun 04 '14 at 19:53
  • Shorter? Yes, apparently, though that will hardly matter when it's gzipped. The one without `with` will execute faster though. I'm not exactly sure about the memory consumption during execution, but the lasting impact is the same. – Bergi Jun 04 '14 at 19:55
  • ...like always.. your answers are clear like the water in some hidden seas in new zeland. +1 what do you think about breaking the reference with this.onload=null. or should i use removeEventListener? naturally that would break the whole time i spend looking into with / reduce the compatibility with older browsers. – cocco Jun 04 '14 at 19:58
  • That's the reference *to* the event listener, I don't know why you would want to break that (preventing the listener from being fired?). It makes your function rather a no-op. I talk about the reference from the background HTTP code that is loading the file *to the image object*. I don't know how exactly browsers handle that, maybe they re-create the JS object when necessary. You would only be able to avoid this by not calling `new Image` and setting a `src` on it to trigger loading. – Bergi Jun 04 '14 at 20:03
  • Removing the `onload` field after the event has been fired (for compatibility with borken browsers) should not be necessary here, as there is no circular reference established. – Bergi Jun 04 '14 at 20:05
  • right... no circular.An reguarding the filereader that one is not compatible with old browser... so the with function is the better one. and if using in a sequential way then i should store new Image somewhere and change only the src.thank you.but this is async,... so i could overwrite. – cocco Jun 04 '14 at 20:06
  • btw you need to correct the part with the reference as there is no circular. – cocco Jun 04 '14 at 20:21
  • I never stated there was a circular reference anywhere? – Bergi Jun 04 '14 at 20:24
  • "Actually, I don't think the object is garbage-collected" – cocco Jun 04 '14 at 20:27
  • in a modern browser if there is no circular reference the object should be added to the garbage collection. – cocco Jun 04 '14 at 20:28
  • @cocco: Because I think that an Image object that is currently loaded (and has event handlers attached to it) becomes a *root* reachable object, which prevents it from being garbage-collected. There is no circular reference, which will get it properly collected both in old and modern browsers *as soon as there is no other reference to it*. – Bergi Jun 04 '14 at 20:35
  • this above sentence is not so clear.. your saying it prevents from being garbage collected because of a eventhandler attached but then you say it's collected both in old and new browsers because of no circular reference.... which one now is appliable to my code? – cocco Jun 06 '14 at 13:05
  • Both. There is a root reference to it *while it is loading* (preventing it from being garbage collected), and *after the load listener is executed* there probably is no more reference to it which will make it being collected. – Bergi Jun 07 '14 at 11:26