How to store HTML Elements as global variable in the console - javascript

When I use chrome developper tools, for any variable that I logged to the console using console.log, I can right-click and select Store as global variable, except if I log a HTML Element.
I found a workaround: if using console.log([el]) instead of console.log(el), it is possible to save the array to a global variable and then use temp1[0] to access the element.
This seems somehow cumbersome. Is there another way to store a console.logged element in a global variable in the console ?

You can use $$(selector)
ƒ $$(selector, [startNode]) { [Command Line API] }
then use the procedure described at the Question.

$_ returns the last logged item in the console.
Beware, though, that it might return undefined if you use console.log(), because if you do console.log('hi!');, then it will also return undefined. To workaround:
/*just type value instead of console.log*/
'hello!';
var text=$_;
/*If you cannot do this, just log it in this way:*/
x.valueOf();
var xContent=$_;

Related

javascript variables returns strange outputs

I'm new here and new to Javascript. I got a strange problem here when I output the values to the console. As far as I know In both these cases the name, and the color is the properties of object car to access them we need to use this.propertyName or object.propertyName, but when I output those values to the console without using this or object name, 1st console.log returns an empty string and the other one returns the uncaught reference error. are they pointing to the window object? then in both the cases, it should return a uncaught reference, can somebody here please clarify this.. thanks in advance. :)
var car = {
name : "ford",
color:"red",
log : function(){
console.log(name);
// outputs an empty string
console.log(color);
// Returns error (this.js:8 Uncaught ReferenceError: color is not defined)
}
}
car.log();
Try console.log(this.name) and console.log(this.color).
Additional Information from MDN
When a function is called as a method of an object, its this is set to
the object the method is called on.
In the following example, when o.f() is invoked, inside the function
this is bound to the o object.
Source: MDN
The reason you don't get a ReferenceError when outputting name is that browsers have a built-in global called name: It's the name of the current window. But they don't have a built-in global called color, so you get the error.
To access name and color on your object when you use car.log(), you'd use this.name and this.color.
yes you are correct both should have thrown uncaught reference but wait ....
actually there is a property on window which is .. yeah ... name
so actually you console that property of window.. ie window.name
.. second one is just correct .. uncaught reference

Strange behaviour with angularJS $scope.$parent

I'm have having some trouble accessing a value from the parent scope, and what appears to be some strange behaviour also.
If I log $scope.$parent to the console and inspect the DOM object there is a property topicDiscovery.name. However, when I try to log this ($scope.$parent.topicDiscovery.name) it returns undefined.
Also, when I try to log the topicDiscovery object it returns an empty array, even though when its not empty in the DOM for $scope.$parent.
Why is this?
This means $scope.$parent.topicDiscovery is getting changed after console.log. Google chrome doesnot print all json object when you do console.log. It just refer to current Object. Try using JSON.stringify($scope.$parent), Here you will not get this property as stringify converts that JS object to string and there will not be any memory linking between orignal object and string.
Here is best example.
var d={z:{b:{}}};
console.log(d); //When you check here, d.a_1 is available
console.log("d.a_1",d.a); //Here d.a_1 is not available.
//Here I am adding d.a_1 property
for(var i=0;i<10;i++){
d['a_'+i]=i;
}

Assign console.log value to a variable

How can I assign a JavaScript object to a variable which was printed using console.log?
I am in Chrome console. With Ruby I would use test = _ to access the most recent item printed.
If you want to do this to an object that has been already logged (one time thing), chrome console offers a good solution.
Hover over the printed object in the console, right click, then click on "Store as Global Variable". Chrome will assign it to a temporary var name for you which you can use in the console.
You could override standard console.log() function with your own, adding the behaviour you need:
console.oldLog = console.log;
console.log = function(value)
{
console.oldLog(value);
window.$log = value;
};
// Usage
console.log('hello');
$log // Has 'hello' in it
This way, you don't have to change your existing logging code. You could also extend it adding an array and storing the whole history of printed objects/values.
In Chrome developer tools, you may access last item by $_:
> 1+1;
2
> $_
2
Derivative of mirrormx's answer, but more convenient. I don't need to write a function and can just put it in anywhere on the spur of the moment.
console.log(window.$log = data);
Here is chrome reference for comand line api.
There is $_ variable but it "Returns the value of the most recently evaluated expression" not printed, you can make your own log function like this:
function log(data){
console.log(data);
return data;
}
// after that you can access last printed value by $_
Please, note that my function is for example, console.log possibilities is much more advanced

Why does the delete keyword act opposite to expected?

In Chrome, try the following in the console. First
console = 0;
to assign the value 0 to console. Then
console // (prints `0`)
to check we have correctly overwritten console. Finally,
delete console
Surprisingly, console now holds the original Console object. In effect, the delete keyword "resurected" console, instead of exterminating it!
Is this expected behaviour? Where is this implemented in the Chromium code?
As mentioned in MDN's documentation on delete:
If the delete operator succeeds, it removes the property from the
object entirely, although this might reveal a similarly named property
on a prototype of the object.
Your delete simply unshadows native property inherited through prototype chain.
Some browsers have window inherit from native prototype and you'll have check out sources to see how property is inherited, if you really want to know that much details, but mostly they work just like JS' own.
Got it:
I've managed to prove the console is a property of the global object: just open your console and type: this.parent or window.parent. This will show a more complete list of properties and methods at your disposal. Including console: Console, about 2/3 of the way down, just below chrome: Object (interesting...:)). I thought of this when I remembered that I somehow managed to change the CSS rules of the console itself (in chrome, don't ask me how I got there, I can't remember). Bottom line: console ís a property of the window object. I think this backs up my explanation rather well.
#Randomblue: Since you're interested in how this is implemented in v8 you can check the trunk here, or browse the bleeding. Somewhere you'll find a test dir, that has a number of files that deal with delete. Special attention is given to delete used on global variables/properties: they can't be deleted, in other words: the console is never really gone. I would like to know why this answer went from being voted helpful and accepted to not-helpful and not-accepted, though...
It's perfectly simple. Console isn't some random, stand-alone, object. It's actually a property of the global object. Open your console and type this.console === console or window.console === console. It logs true, of course.
So thanks to implied globals console = 0 is pretty much the same as window.console = 0. You're sort of reassigning a property of an instance. The difference with normal objects is that the global object isn't just any old object: it's properties cannot be deleted (somewhere here on MDN). So your global is masking the console object, which is still there, you've just lost your reference too it:
var bar = window.console;
console = 12;
bar.log(console);//logs 12, bar is now an alternative reference to the console object
delete console;//unmasks the console reference
console === bar;//true
Don't, for a moment, be fooled into thinking the global object doesn't have a prototype. Just type this.constructor.name and lo and behold: Window with a capital W does appear. Another way of double checking is: Object.getPrototypeOf(this); or Object.getPrototypeOf(window);. In other words, there are prototypes to consider. Like always, the chain ends with Object.prototype:
Object.getPrototypeOf(Object.getPrototypeOf(window));
In short, there is nothing weird going on here, but the weird nature of the global object itself. It behaves as if there is some form of prototypal inheritance going on. Look at the global object as though it were set up like this:
this.prototype.window = this;//<-- window is a circular reference, global obj has no name
this.prototype.console = new Console();//this is the global object
this.hasOwnProperty(console);//false
console = 0;//implied global
When attempting to access console, JS finds the property console you've just set prior to the instance of the Console object, and happily returns its value. The same happens when we delete it, the first occurance of console is deleted, but the property higher up the prototype chain remains unchanged. The next time console is requested, JS will scan the inheritance chain and return the console instance of old. The console-object was never really gone, it was merely hidden behind a property you set yourself.
Off topic, but for completeness' sake:
There are a few more things too it than this (scope scanning prior to object/prototype chain searching), due to the special character of the global object, but this is, AFAIK, the essence of it.What you need to know is that there is no such thing (in JS) as an object without (at least) 1 prototype. That includes the global object. What you're doing merely augments the current global object's instance, delete a property and the prototype takes over again. Simple as that. That's what #Peeter hinted at with his answer: implied globals are not allowed in strict mode, because they modify the global object. Which, as I tried to explain here, is exactly what happens here.
Some properties of the window object aren't deletable. True is returned because you aren't running in strict mode. Try the following (not in console):
"use strict";
delete console;
and you will get an exception (JSFiddle).
You can read more about how this is handled at http://es5.github.com/#x11.4.1
First, this is not just the console, you can do this with every native property every browser-defined property on window.
setTimeout = 0;
setTimeout //=> 0
delete window.setTimeout;
setTimeout //=> function setTimeout() { [native code] }
Properties that are part of the ECMA-Script Spec can be fully overwritten & deleted:
Array = 0;
Array //=> 0
delete window.Array;
Array //=> ReferenceError
You can nearly overwrite any property on window, delete the overwrite and get back to the normal function.
The simple reason for this is that console and all the other native global functions browser defined properties are not linked to the DOMWindow Object via javascript but via C++. You can see the console being attached to the DOMWindow right here and the implementation of DOMWindow here
That also means that the window object is somehow a C++ Object masked as a javascript object the window object is at least partly defined by C++, and it is not prototypical inheritance doing the magic: Take for example:
window.hasOwnProperty('console') //=> true, console is defined directly on the window
window.__proto__.hasOwnProperty('console') // => false, the window prototype does not have a console property
Also, if it was prototypical inheritance, the following would lead to console returning 3:
window.__proto__.console = 3;
delete console;
console //=> still returns console;
window.hasOwnProperty('console') //=> the window still has it.
The same with a property respecting prototypical inheritance:
window.someProp = 4;
window.__proto__.someProp = 6;
someProp //=> 4
delete someProp;
someProp //=> 6
Therefore, when you set console to anything, it is gone and can only be resurrected by (hoorray for the irony): delete console.
So, what it means is that you cannot delete any native properties on the window object. Try to delete window.console when it is not overwritten, it will just pop up again. The fact that you are able to overwrite it in the first place (even in strict mode) without receiving any kind of warning (in my eyes) one of the key vulnerabilities of javascript (set setTimeout on nearly any page to 0 and see it tear itself apart), but as they say in spiderman:
With great power comes great responsibility
Update
To include a hint that this is specific to the implementation of the browser / engine and not any requirement of the language itself: In nodejs, deleting both engine-specified properties and ecma-script properties on the global object works:
delete this.console //=> true
console //=> ReferenceError
delete parseInt //=> true
parseInt //=> ReferenceError
The exact same thing happens in Firefox.
I'm assuming the following, based on observations of my own.
Variables are first checked to see if they match local variables, if not, then it will be checked to see if they match window.variable.
When you set console to 1, you set the local variable console to 1, so any lookups will see that instead of window.console (which still exists). When you delete console the local variable console gets deleted. Now any lookups of console will match window.console. That's why you get the behaviour you get.
I am assuming this based on experimenting with the JavaScript interpreter in Firefox.
And, I'm sorry about incorrect terminology (feel free to edit), I'm not that experienced with namespaces.
The delete operator removes a property from an object.
...
You can use the delete operator to delete variables declared
implicitly but not those declared with the var or the function
statement.
See delete on MDN
Edit:
See also Understanding delete if you're really into hardcore JavaScript.
What happens is you are overwriting the objects prototype, then you delete the overwritten value and what is left... is the original object, which is it's prototype.
Expected behavior. Little known fact that the Javascript console does not run in the browser's global space, but rather it runs within its own anonymous function.
I know that different browsers handle things differently, but in short -- delete does not operate as expected because it isn't operating in the global space.
If you really want to see things break, try playing with delete window.console
Ok, it is official -- I'm an idiot. One of the new features in ECMAScript is the ability to declare a property as dontdelete. Sorry about that confusion.

Strange IE error - between JavaScript global variable and element with name attribute

I tested the following code in IE6, IE7 and IE8 with the same result:
<a name="cd"/>a</a>
<script>
try {
cd = new Date;
} catch(e) {
alert(e);
}
</script>
In all cases an error is thrown. However using
var cd = new Date;
seems to solve the problem.
Does anyone know why that is ?
Here is an example: http://jsbin.com/ahuhu4/2
When you don't use the var specifier to declare your variable, the variable cd is added as a property to the window object, e.g. window.cd. You already have an object element that is a child of window that is <a name="cd">a</a> which is already typed. You can't specify new Date as a type for this object as it already exists. When you use the var keyword, you are rescoping the variable to a local scope and removing its direct attachment to the window object. This removes the error and allows IE to proceed. Other browser engines handle this differently.
IE does you the great favor of creating properties of window for each page element with an "id" value. It's just a thing. (note: this statement is not really true.)
edit — yes, the element doesn't have "id". OK, well good news - IE also treats references by name as if they were by "id". Recall that document.getElementById("cd") on that page would return a reference to the <a>, just as it would if it had an "id" element.
edit again I think it's not quite correct to say that IE creates actualy window properties, at least by my reading of what the IE8 debugger is telling me. It's more like the interpreter treats an implicit reference to a global variable ("cd" in this case) as a request for it to go look for something in the global page context by that name. To IE, that process includes checking the DOM for elements with that "id" or "name" value. By using the var keyword, you're explicitly telling the interpreter that you're declaring a symbol in the applicable scope (global, here), so that "lookup" process is skipped.
//
Firefox does not automatically define global variables for elements with ids or names.
IE including #9, Opera 10, Safari 5 and Chrome 6 all do maintain a global
rollcall of named or id'd elements in the document.
It seems like it could crowd up the global namespace...
function a1(id){
try{
window[id].style.color= 'red';
}
catch(er){
return er.message+'\n'+'window.'+id+' = '+window[id];
}
return 'window.'+id+'='+window[id];
}
function a2(id){
window[id]= 'red';
return 'window.'+id+'='+window[id]
}
/*
firefox returns window[idstring] is undefined.
The others all find it, just like the old IE document.all object.
query the id as a global identifier:
alert(a1('idstring'))
colors the element red and returns[object HTMLButtonElement]
(returns [object Object] in older ie browsers)
assign the global a new value: alert(a2('idstring')) returns 'red'
Try the element again alert(a1('idstring'))
throws an error - Cannot convert 'window[id].style' to object
or Cannot set property 'color' of undefined or
Result of expression 'window[id].style' [undefined] is not an object ot
Object expected
*/

Categories

Resources