Custom string instead of "Object" in console.log - javascript

For convenience while debugging, I think it would be nice to print some custom string, rather than the default Object that appears when logging an object to the console.
In the following example, see how an object called example is marked by Object when it is logged to the console, whereas window is marked by Window when it is logged to the console. I guessed that the __proto__["Symbol(Symbol.toStringTag)"] property might be the way to go, since window's is set to Window. That didn't work, but maybe I'm just using it wrong.

That's because you're using the Symbol wrong -- you were on the right track. Symbol.toStringTag is a special well-known Symbol used by Object#toString to give you the console output, specifically the tag you're after. You can't wrap it in a string as you've done, or else you'll be literally setting the "Symbol.toStringTag" property, not the actual Symbol:
const example = {
key: "value"
};
example.__proto__["Symbol.toStringTag"] = "Example";
console.log(example); //You set the literal "Symbol.toStringTag" property -- wrong
Instead, don't wrap it in quotes and actually set the Symbol:
const example = {
key: "value"
};
example.__proto__[Symbol.toStringTag] = "Example";
console.log(example);
Which produces (on Chrome):

Related

Javascript String Array-Like-Object behaviour

When I run above code in Chrome dev console, I do not get any error. But when same code runs via js loaded on a webpage I receive this exception -
Cannot create property 'name' on string 'some string'
Can someone please tell me why there is different behaviour in above 2 cases?
Your webpage must be running that snippet of code in strict mode, in which assigning to properties of a string will throw an error:
'use strict';
const str = 'foo';
str.bar = 'bar';
In sloppy mode, it'll just fail silently:
const str = 'foo';
str.bar = 'bar';
Strings are a value objects as in they have a value not a reference to an instance of an object, they cannot have properties set with a["name"] like reference objects can.
a[3] is the 4th character in the string, a[0] being the first.
Let's see this case
const a = "a"
Object.isFrozen(a) // true
const b = new String("b")
Object.isFrozen(b) // false
From this section, we could see that String objects are not necessarily frozen. Only those string literals are frozen (I think it's because they are shared in a pool. If they are not frozen, you can create properties on one place to affect the code elsewhere) However, the explicitly constructed String objects are independent from the pool, thus not frozen.

Get a variable from Object Symbol

I have an object that when inspected by Developer Tools Console looks like this:
console.log("clicked: ", clickedMarker);
How can I get the address content form Symbol(vars)?
console.log("vars: ", clickedMarker["Symbol(vars)"]);
console.log("address: ", clickedMarker.address);
console.log("address2: ", clickedMarker["address"]);
console.log("vars2: ", clickedMarker["vars"]);
console.log("vars3: ", clickedMarker.vars);
console.log("Symbol(vars): ", clickedMarker._objectInstance["Symbol(vars)"]);
but it all comes out undefined.
Edit: This is a Typescript application but the Javascript solution worked fine.
The issue is likely that you are looking for a string key instead of a symbol one.
To read more about what a Symbol is (which is a primitive in javascript, anyway), please check this: https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Symbol
To solve the issue, find the correct Symbol by using the comfortable toString prototype, and make use of the getOwnPropertySymbols method of the generic Object:
// look for the symbol having key "vars" in the object's symbols list.
var mFound = Object.getOwnPropertySymbols(clickedMarker._objectInstance)
.find(e => e.toString() === "Symbol(vars)");
// Use the above symbol as the object's key.
var address = clickedMarker._objectInstance[mFound].address;
Please remember that, for further safety, you should check if mFound is effectively found (hence NOT undefined, or generically not falsey).

name already defined in console!?

Could anyone explain why this code returns
""
in firebug console?
Don't down-vote thinking it's just a typo! :O
I was curious to know why it doesn't throw an error!!!
function mds() {
var {
namex,
score,
className
}
= {
namex: 'NAME',
score: '10',
className: 'Oop'
};
this.test = function () {
return name;
};
}
var x = new mds();
x.test()
I would also love to hear more details on this type of variable mapping (or a link) ?
UPDATE:
I would like to know why name is predefined with value "" in console?
The JavaScript part of the explanation here is simple.
When you do this:
this.test = function () {
return name;
};
It will first look for a variable named name in the scope of the function this.test(). When name is not found there, it will check in the parent function's scope as well. And since name is not defined there as well, it will look in the global scope, which is window, and returns the value of window.name, which in this case is an empty string. This (window.name) is what you are seeing when you run name in the console (or Firebug). This much is simple.
The value of window.name is decided according to it's definition in the HTML Standard (not according to ECMAScript rules). This MDN page says:
window.name - Gets/sets the name of the window.
And in your case, the name of the window is empty, hence the empty string you are getting. That's the simpler explanation of why window.name is empty.
If you really want to understand why window.name is empty here, you need to check out the HTML Specification for what it says about browsing contexts. It says that the value of window.name will be the name of the current browsing context.
A browsing context is an environment in which Document objects are presented to the user. (from the spec)
For example, when you create a link in HTML using the below code, the target attribute specifies the target browsing context in which the page is to be opened.
Click me
See more examples in this JSBin.
Hope this was somewhat helpful. Read the HTML Spec to understand more about browsing contexts.
Even if you run the below code you get "".
function ha() {
return name;
}
ha();
returning of "" has no way related to
var {
namex,
score,
className
}
= {
namex: 'NAME',
score: '10',
className: 'Oop'
};
Another way to test it is, Just type 'name' press enter in console.
""
Updating as per "Krishna" observation.
Looks like name is predefined in console context. So if the user doesnt have another declaration of name within the scope the console returns an empty string "". If user has declared name="xyz" then xyz is returned
name is a legitimate window property.
Windows can have names. And they can be useful.
As in:
Open a new window, with the name of namedWindow!
...and to make this more informal, we should add that: a link with a named target will either open in an existing window with that name or will create a new one with the given name in case it's not.
And because the "name" token is a global property of the window context; stating: name in the console or anywhere in the script will of course return an empty value (of a proper/accepted type), that is: a string. In this case [meaning the window.name hasn't been defined yet] an empty ("") string, is the only correct value for that property.
Whereas an unset event of a window, or any DOM element - if it exists - should return null, not undefined or god forbid an empty string, because they (event properties) expect functions; and functions are of type object, and null represents an empty object.
However, an unset, inline event attribute of an html element - should return an empty string ("").
Try this,
var {
namex: name,
score: score,
className
} = {
namex: 'NAME',
score: '10',
className: 'Oop'
};
actually object have to be key value pair

Equivalent of Python's KeyError exception in JavaScript?

I am trying to access a certain member in a JavaScript object. In order to do this, I need to try out a couple of key values.
For example, Object['text/html'] which will give me an export link for a HTML document. However, not every object of this type will have a text/html key pair value.
In Python I would solve this problem using a Try-Catch block, with the KeyError exception. If I can do something similar in javascript, as in use an exception in a Try-Catch block, that would be great.
However, if alternatives exists instead of try catch blocks, that do achieve the same end goal, I would like to know about them as well.
EDIT:
I would prefer to use an exception over using functions. I do this because the text/html key might not be there, but it should be there. An exception seems more appropriate for this scenario
Javascript doesn't generate an exception when reading or writing a property that doesn't exist. When reading it, it just returns undefined. When writing it, it just creates the property.
You could create your own function that tests to see if the property exists and throws an exception if it does not (but you'd have to call that function whenever), but JS doesn't make an exception out of that on it's own like you are asking for.
If you want to test if a key exists on an object in javascript, you can use this construct with the in operator:
var obj = {};
var key = "test";
if (key in obj) {
// key exists
} else {
// key doesn't exist
}
If you try to read a key that doesn't exist, you will get undefined as the value.
var obj = {};
var value = obj.test;
alert(value === undefined);
The in operator does a better job of telling you whether the key exists that testing for undefined because undefined is a legal value for a key that exists.
In many cases, where you control the values that the keys have and a key that is present will never have a falsey value, you can also just check if the key has a truthy value:
var obj = {};
var obj.test = "hello";
if (obj.test) {
// key exists and has a truthy value
}
If you want to make sure that the object itself has the property and not any prototype that it is inheriting from, then you can do this:
var obj = {};
var obj.test = "hello";
if (obj.hasOwnProperty(test)) {
// key exists on the object itself (not only on the prototype)
}
Read this!
The accepted answer is correct however omits some points.
1) Accessing nested object
Like someone pointed out in the comment, Javascript returns undefined when the key doesn't exists in the object.
However, if you need to access an object inside an object (or an Array, or a function), well this break.
let a = {};
let userName = 'js'
let data = a.response[userName];
Cuz you will received actually a TypeError, basically because we are trying to read a property of undefined, which doesn't have any.
VM187:2 Uncaught TypeError: Cannot read properties of undefined (reading 'js')
at <anonymous>:2:22
2 Answering the question
The Python principle "Ask forgiveness not permission" - explain is actually for the most part working well in Javascript (and PHP, you didn't ask but well..). There are for sure some difference, or some situation where the difference is important, but for most use cases is the same
So this is how you would do it:
try {
let data = a.key1.key2['whatever'].nested.damn.object;
console.log(data)
} catch (error) {
let data = "noope";
console.log(data);
}
As you can see, in Javascript you don't really care about the error type, (for the most part, sure other situation you should case). Is almost like anything is in a Python's
try:
a = "hello" + 1 + {} + [] # crazy stuff here
except BaseException as bleh:
print(str(bleh))
Documentatin
MDN Working with objects
How do I check if an object has a key in JavaScript? [duplicate]

JavaScript object.hasOwnProperty() with a dynamically generated property

I have an object that I am passing to a function, that I am trying to figure out if the property exists or not, and when it doesn't, ignore it.
The problem is I keep getting false even when the property is there. For sake of example, I will use an object I posted on another question earlier today...
var myObj = {
something1_max: 50,
something1_enabled: false,
something1_locked: true,
something2_max: 100,
something2_enabled: false,
something2_locked: true,
something3_max: 10,
something3_enabled: true,
something3_locked: true
}
which gets passed to a function like: buildRetentionPolicyStr('something2', myObj);
So far I’ve got everything I need with this function working perfectly. Until I tried it on live data and realized on the occasion, properties I thought were static and there with defaults otherwise aren't always actually there. So I need to do something I assume with hasOwnProperty() somehow. So in my function I can set a default of my own where if the property exists, use it..
I.e.:
function buildRetentionPolicyStr(theScope, obj)
{
var myVar = 0;
if(obj.hasOwnProperty(theScope + '_enabled'))
{
myVar = obj[theScope + '_enabled'];
}
}
In my current test case, the object does in fact exist, so I know that to be true. However, when I do (right above the if statement):
console.log(obj.hasOwnProperty(theScope + '_enabled'));
// Or
console.log(obj.hasOwnProperty([theScope + '_enabled']));
I get this output respective to the order above:
false
// Or
["something2_enabled"]
What is, if there is one, the proper way to check to see if the property exists in this fashion?
A simple way to do that is to run typeof against your property:
obj = { xxx: false }
typeof obj.xxx // 'boolean'
typeof obj.yyy // 'undefined'
I ended up doing a review of my code to figure out overall that I had some mix matched cases. While I was in all doing what I should have, I overwrote one of my variables and caused the object I was looking for to essentially to end up going missing. So in fact false was correct.
So to verify the how or which was proper for me in my case.
obj.hasOwnProperty([theScope+'_enabled']);
was the proper way.

Categories