I was wondering despite of memory leak, what is the use of a circular reference in javascript? Even window object in the browser is circular referenced like window.window.window ...... Why we are using it and where we can use it. What are the good parts of it?
I was wondering despite of memory leak,
There is no memory leak, two objects that reference each other but are not linked anywhere else get garbage collected. The window object will never be collected, so it doesn't matter here nevertheless.
what is the use of a circular reference in javascript?
Like in any other language they can be used for various structures, such as trees (parent <-> child), linked lists (left <-> right) and many-to-many relationships (students <-> classes). Not having them would complicate some forms of traversal and would make programs significantly slower.
Why is window.window a circular reference?
window is not only an object, but it is also the most global scope where all variables are finally looked up. When you use any global variable, such as setTimeout, it gets looked up in the global scope, and therefore the window object.
window.setTimeout === /*window.*/setTimeout
Now if you want to refer to the global object, it has to be looked up in the global scope, which is itself the global object.
window.window === /*window.*/window
Therefore just the window already accesses the circular reference, it is the reason why the global object can be found at all. Otherwise window would have to be a reserved keyword.
see this page, great reasons are there
Why window.window property exists?
The point of having the window property refer to the object itself, was likely to make it easy to refer to the global object. Otherwise, you'd have to do a manual var window = this; assignment at the top of your script.
Another reason, is that without this property you wouldn't be able to write, for example, "window.open('http://google.com/')". You'd have to use "open('http://google.com/')" instead.
.
and see this answer also
https://stackoverflow.com/a/35788599/1475257
Related
As a JavaScript newcomer I see a lot of magic which isn't explained in books. For example, why can I write
document.getElementById('one');
When document is a property of window? From what I've read in books, we need to write
window.document.getElementById('one');
If document would be regular object like any object we would create by ourselves.
What allows us to omit window parent object while working with document property?
I googled this, but I couldn't find an explanation.
window is the Global object in a browser and because of the way scope works in JavaScript, the Global object will always be the last place that is searched for something. So, omitting window is OK because it will wind up being found at the end of the "scope chain".
document is a property of window and, as such, you do not need to qualify it with window for it to be found because when the browser reaches window and still hasn't found what it's looking for, it will look at the properties of window and find document there.
window represents the browser's window.
All global JavaScript objects, functions, and variables automatically become members of the window object.
document is also a property of global object and hence can be accessed as window.document or document.
For more information, you can refer here.
The global window object stores properties specific to the environment (for example, window.innerHeight).
But if we print window to the console, we will see the properties highlighted in a different color.
These include Array, Object, and so on, although i thought they are internal objects.
I have a few questions:
What are these "implicit" properties?
Where do JS boundaries end and environment begin?
Can I refer to Array in Node.js, for example?
Thank you.
In the early days of Javascript, there was one master global symbol and everything that was available in the global scope whether it was part of the language itself or part of the browser environment was a property of that master global.
In the browser, that master global is the window object. Thus, you see many things on the window object that are available globally like the Array constructor.
I would guess that this is a side effect of that fact that Javascript was first designed to run in a browser and was not initially a completely stand-alone language with a stand-alone specification.
More recent revisions to the language specification are not adding some new things to the window object any more. For example, when you declare an ES6 class such as:
class Foo {
constructor(greeting) {
this.greeting = greeting;
}
}
You will not find Foo on the window object even though it may be globally available in the browser.
As others have said, the color difference in the debug output has to do with whether the symbols are enumerable or not which is a technical distinction on whether the property shows up in something like Object.keys() or a for/in loop. The property is still there and is accessible either way.
I'm trying to learn more about Web APIs. Reading about them I see that among the wide variety of web API's there's the DocumentObjectModel API. Reading about the DOM specifications, I find a list of a lot of DOM interfaces. This makes me feel a little upset. In my ignorance, I think that an API should contain only one interface (only one set of functions and properties), here I find a list of interfaces...and that's the first thing that I don't understand.
Moreover, I usually interact with the DOM using notations like
document.getElementById("idname");
document.getElementByTagName("tagname");
etc ect
I see that some of these DOM interfaces have names that I already know, like "Document" or "Window", I use them (like in the previous two lines of code) but I use them not capitalized ("document" rather than "Document"). I don't understand if there is a link beetwen "document" and "Document", for example...
Finally, I noticed that querying for the global object (in the browser console, for example, simply typing the keyword "this") I have in response an object that (I guess) contains all the properties and functions (or methods) of the global object. And among them there are also functions that have the same names listed in the DOM interfaces list. And that's simply another thing that I noticed that I'm not able to explain.
So, can you help me to understand more deeply DOM API?
Those things arise from an interaction of javascript and the DOM specifications.
The capital-letter Window and Document are interfaces defined by the DOM and HTML specs.
In Javascript, when executed in a browser environment, an instance of Window is the global object and Window is its prototype. document and window are getter properties defined by those interfaces. Since the window is the global object (the top-level this) and variable name resolution walks up the scope chain and finally lands at the global object if it cannot find it elsewhere window will eventually resolve to <global object>.window. Which is the attribute defined on the Window interface, which returns the window instance itself, which also is the global object. It is self-referential.
So the global object ends up having properties defined by javascript, by the dom/html specs and inherited from the prototypes also defined by those various specs.
Some prototypes are also exposed as named properties in the global object and not just the prototype chain of the instances. This is convenient for instanceof checks and feature detection. Some constructors are also exposed, e.g. new Image() creates a new instance of HTMLImageElement the same way document.createElement("img") would.
Additional Document instances can created via various constructors or factories such as DOMParser. Additional Window instances might be accessed through frames, the page's opener or spawned child windows.
Looking at the window object with a debugger may help.
In a lot of code examples I see around the internet, global variables such as innerWidth, onresize, navigator, etc., are written as window.innerWidth, window.onresize, window.navigator, respectively.
Why are some of these globals prepended with window. and others, such as document and console typically not prepended?
Edit:
I know how OOP works and that I am accessing various properties of the window object. I'm no novice to JavaScript. I'm sorry if my question may have been unclear. I have been programming in JS for years but have never questioned this convention, hence my question.
In essence, I am asking why we don't put window. before document, but we put it before innerWidth. Is it simply a matter of clarity? In theory, shouldn't I be able to reference any of the globals without the window. prefix and have no problem?
It's unfortunate but window in your browser refers to one object which represents two logically distinct concepts :
an instance of Window, an object with well defined properties like Window.innerWidth, logically mapped to your browser's window (or rather the tab, today, but that distinction is hidden from your script)
the global object to whom all global variables are attached as properties
Semantically, it's cleaner to not prefix the global variables, unrelated with the Window concept, with window..
Now note that this introduces a problem when you refer to your global specific variable like myThing : it's hard to know if you're knowingly referring to a global variable or if it's declared in some intermediate scope (or if you just forgot to declare the variable with var). which leads to a situation in which you won't use window. only for properties of the instance of Window but also for your specific global variables. Of course in practice you'll avoid global variables as much as possible.
Not prefixing with window. also has the advantage, when you forget a var declaration or a library import, to make your code fail fast in a not subtle way (which is better than failing in production in a hard to debug way) :
window.undeclaredVariable // no error, just an undefined value
undeclaredVariable // reference error
JavaScript would probably have been better with a distinction between those two concepts (something like global or root as in node).
All the global functions and variables are attached to the object activator, this object dependent of your host environment (browser, node, etc), in the browser environment the object activator is the window object, so each global function could be access with window.console, this.console or just console, I think the prepend is useful to have a more readable code.
You could access to global scoped variables without the window prepend just innerWidth.
Think of it like objects. You are trying to get the innerWidth of the window object its self. Document is the same way. You are trying to get those variables that describe the document itself instead of the window as a whole. And console is just that, a console that you console.log to for debugging. It also has its own properties.
They may be global variables, but they still belong to and describe a specific "object" that you must call on first. If that makes sense.
I was reading Google's Javascript style guide regarding closure (http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml#Closures) and I wonder whether it is safe to use jquery proxy to execute a callback while not fall into the memory leak trap?
The thing to remember about closures in any managed memory environment is how the garbage collector works. It starts with root objects like "window" and follows every possible memory reference. If it can find an object, then that object can't be reclaimed.
The key is to cut all possible paths when you no longer need the closure. That includes the closure-referencing function, all objects that reference the function, and the object that owns the function. That would include any proxies; null out references to those as well.