How exactly does the JavaScript expression [1 [{}]] parse? - javascript

Can you explain how the JavaScript expression:
[1 [{}]]
parses/evaluates? In Firefox, Chrome, Konqueror, and rhino, it seems to create an array with a single element, undefined. However, I don't understand why.
In Firefox:
[1 [{}]].toSource()
produces
[(void 0)]
Replacing 1 with other JavaScript values seems to yield the same result.
Update: I think I understand now. codeka, Adrian, and CMS clarified things. As far as the standard, I tried to walk through ECMAScript 5.
1 [{}] is a Property Accessor, so it's covered in §11.2.1.
baseReference is the result of evaluating 1, so still 1.
baseValue = GetValue(baseReference) == 1.
At GetValue (§8.7.1), Type(1) is not Reference (a resolved name binding), so return 1.
propertyNameReference is result of evaluating {}, so an empty object.
propertyNameValue = GetValue(propertyNameReference) == {}
At CheckObjectCoercible(baseValue) (§9.10), we return (Number is object-coercible).
propertyNameString = ToString(propertyNameValue)
At ToString (§9.8), return ToString(ToPrimitive({}, hint String))
At ToPrimitive (§9.1), return result of object's [[DefaultValue]], passing PreferredType (string).
At [[DefaultValue]] (§8.12.8), let toString be result of [[Get]] with argument toString.
This is defined at §15.2.4.2 to return "[object " + [[Class]] + "]", where [[Class]] is "Object" for the default object prototype.
Since there is a callable toString, we call it with argument this being {}.
Return a value of type Reference, whose base value is BaseValue (1) and whose referenced name is propertyNameString ("[object Object]").
We then go to Array initializer (§11.1.4), and construct a single element array with the result.

Reading the OP and Nick comments, I think I can expand a little bit more the Adrian's answer to make it clearer.
It's perfectly valid JavaScript.
JavaScript handles object property names as strings, objects cannot contain other types or other objects as keys, they are just strings.
The bracket notation property accessor (MemberExpression [ Expression ]) implicitly converts the expression between brackets into a string, so:
var obj = {};
obj[{}] = "foo";
alert(obj["[object Object]"]); // foo
In the above example you can see that I assign a value to the {} property, and {}.toString() (or {}+'') produces the string "[object Object] (via Object.prototype.toString).
The expression 1 [{}] implicitly converts the 1 Number primitive to an object (this is made by the property accessor) and it lookups a property named "[object Object]" the property lookup is made on the Number.prototype and the Object.prototype objects, for example:
1['toString'] === Number.prototype.toString; // true
Finally, the 1 [{}] expression is itself enclosed in brackets ([1 [{}]]), this is actually an Array literal.
In conclusion here is how the parser evaluates the expression:
[1 [{}]];
// ^ The accessor expression is evaluated and converted to string
[1 ["[object Object]"]];
// ^ A property lookup is made on an Number object
// trying to access a property named "[object Object]"
[undefined];
// ^ the property is obviously not found
[undefined];
//^ ^
// An array literal is created with an element `0` which its value is `undefined`

It is because you are trying to get the property {} of the object 1 and then place it in an array. 1 doesn't have the property {}, so 1[{}] is undefined.
If you replace the 1 with an array, you will see how it is working. With 1 as [5] and {} as 0, it is [[5][0]].
Also, keep in mind that obj['property'] is the same as obj.property.

If we break it up a bit, you'll see:
var foo = 1;
var bar = {};
var baz = foo[bar];
[baz];
I believe it's valid JavaScript, but I'm not an expert...

Related

How to read an array of data [duplicate]

I am trying to alert a returned value from a function and I get this in the alert:
[object Object]
Here is the JavaScript code:
<script type="text/javascript">
$(function ()
{
var $main = $('#main'),
$1 = $('#1'),
$2 = $('#2');
$2.hide(); // hide div#2 when the page is loaded
$main.click(function ()
{
$1.toggle();
$2.toggle();
});
$('#senddvd').click(function ()
{
alert('hello');
var a=whichIsVisible();
alert(whichIsVisible());
});
function whichIsVisible()
{
if (!$1.is(':hidden')) return $1;
if (!$2.is(':hidden')) return $2;
}
});
</script>
whichIsVisible is the function which I am trying to check on.
As others have noted, this is the default serialisation of an object. But why is it [object Object] and not just [object]?
That is because there are different types of objects in Javascript!
Function objects:
stringify(function (){}) -> [object Function]
Array objects:
stringify([]) -> [object Array]
RegExp objects
stringify(/x/) -> [object RegExp]
Date objects
stringify(new Date) -> [object Date]
… several more …
and Object objects!
stringify({}) -> [object Object]
That's because the constructor function is called Object (with a capital "O"), and the term "object" (with small "o") refers to the structural nature of the thingy.
Usually, when you're talking about "objects" in Javascript, you actually mean "Object objects", and not the other types.
where stringify should look like this:
function stringify (x) {
console.log(Object.prototype.toString.call(x));
}
The default conversion from an object to string is "[object Object]".
As you are dealing with jQuery objects, you might want to do
alert(whichIsVisible()[0].id);
to print the element's ID.
As mentioned in the comments, you should use the tools included in browsers like Firefox or Chrome to introspect objects by doing console.log(whichIsVisible()) instead of alert.
Sidenote: IDs should not start with digits.
[object Object] is the default toString representation of an object in javascript.
If you want to know the properties of your object, just foreach over it like this:
for(var property in obj) {
alert(property + "=" + obj[property]);
}
In your particular case, you are getting a jQuery object. Try doing this instead:
$('#senddvd').click(function ()
{
alert('hello');
var a=whichIsVisible();
alert(whichIsVisible().attr("id"));
});
This should alert the id of the visible element.
You can see value inside [object Object] like this
Alert.alert( JSON.stringify(userDate) );
Try like this
realm.write(() => {
const userFormData = realm.create('User',{
user_email: value.username,
user_password: value.password,
});
});
const userDate = realm.objects('User').filtered('user_email == $0', value.username.toString(), );
Alert.alert( JSON.stringify(userDate) );
reference
https://off.tokyo/blog/react-native-object-object/
Basics
You may not know it but, in JavaScript, whenever we interact with string, number or boolean primitives we enter a hidden world of object shadows and coercion.
string, number, boolean, null, undefined, and symbol.
In JavaScript there are 7 primitive types: undefined, null, boolean, string, number, bigint and symbol. Everything else is an object. The primitive types boolean, string and number can be wrapped by their object counterparts. These objects are instances of the Boolean, String and Number constructors respectively.
typeof true; //"boolean"
typeof new Boolean(true); //"object"
typeof "this is a string"; //"string"
typeof new String("this is a string"); //"object"
typeof 123; //"number"
typeof new Number(123); //"object"
If primitives have no properties, why does "this is a string".length return a value?
Because JavaScript will readily coerce between primitives and objects. In this case the string value is coerced to a string object in order to access the property length. The string object is only used for a fraction of second after which it is sacrificed to the Gods of garbage collection – but in the spirit of the TV discovery shows, we will trap the elusive creature and preserve it for further analysis…
To demonstrate this further consider the following example in which we are adding a new property to String constructor prototype.
String.prototype.sampleProperty = 5;
var str = "this is a string";
str.sampleProperty; // 5
By this means primitives have access to all the properties (including methods) defined by their respective object constructors.
So we saw that primitive types will appropriately coerce to their respective Object counterpart when required.
Analysis of toString() method
Consider the following code
var myObj = {lhs: 3, rhs: 2};
var myFunc = function(){}
var myString = "This is a sample String";
var myNumber = 4;
var myArray = [2, 3, 5];
myObj.toString(); // "[object Object]"
myFunc.toString(); // "function(){}"
myString.toString(); // "This is a sample String"
myNumber.toString(); // "4"
myArray.toString(); // "2,3,5"
As discussed above, what's really happening is when we call toString() method on a primitive type, it has to be coerced into its object counterpart before it can invoke the method.
i.e. myNumber.toString() is equivalent to Number.prototype.toString.call(myNumber) and similarly for other primitive types.
But what if instead of primitive type being passed into toString() method of its corresponding Object constructor function counterpart, we force the primitive type to be passed as parameter onto toString() method of Object function constructor (Object.prototype.toString.call(x))?
Closer look at Object.prototype.toString()
As per the documentation,
When the toString method is called, the following steps are taken:
If the this value is undefined, return "[object Undefined]".
If the this value is null, return "[object Null]".
If this value is none of the above, Let O be the result of calling toObject passing the this value as the argument.
Let class be the value of the [[Class]] internal property of O.
Return the String value that is the result of concatenating the three Strings "[object ", class, and "]".
Understand this from the following example
var myObj = {lhs: 3, rhs: 2};
var myFunc = function(){}
var myString = "This is a sample String";
var myNumber = 4;
var myArray = [2, 3, 5];
var myUndefined = undefined;
var myNull = null;
Object.prototype.toString.call(myObj); // "[object Object]"
Object.prototype.toString.call(myFunc); // "[object Function]"
Object.prototype.toString.call(myString); // "[object String]"
Object.prototype.toString.call(myNumber); // "[object Number]"
Object.prototype.toString.call(myArray); // "[object Array]"
Object.prototype.toString.call(myUndefined); // "[object Undefined]"
Object.prototype.toString.call(myNull); // "[object Null]"
References:
https://es5.github.io/x15.2.html#x15.2.4.2
https://es5.github.io/x9.html#x9.9
https://javascriptweblog.wordpress.com/2010/09/27/the-secret-life-of-javascript-primitives/
It's the value returned by that object's toString() function.
I understand what you're trying to do, because I answered your question yesterday about determining which div is visible. :)
The whichIsVisible() function returns an actual jQuery object, because I thought that would be more programmatically useful. If you want to use this function for debugging purposes, you can just do something like this:
function whichIsVisible_v2()
{
if (!$1.is(':hidden')) return '#1';
if (!$2.is(':hidden')) return '#2';
}
That said, you really should be using a proper debugger rather than alert() if you're trying to debug a problem. If you're using Firefox, Firebug is excellent. If you're using IE8, Safari, or Chrome, they have built-in debuggers.
[object Object] is the default string representation of a JavaScript Object. It is what you'll get if you run this code:
alert({}); // [object Object]
You can change the default representation by overriding the toString method like so:
var o = {toString: function(){ return "foo" }};
alert(o); // foo
I think the best way out is by using JSON.stringify() and passing your data as param:
alert(JSON.stringify(whichIsVisible()));
You have a javascript object
$1 and $2 are jquery objects, maybe use alert($1.text()); to get text or alert($1.attr('id'); etc...
you have to treat $1 and $2 like jQuery objects.
You are trying to return an object. Because there is no good way to represent an object as a string, the object's .toString() value is automatically set as "[object Object]".
Consider the following example:
const foo = {};
foo[Symbol.toStringTag] = "bar";
console.log("" + foo);
Which outputs
[object bar]
Basically, any object in javascript can define a property with the tag Symbol.toStringTag and override the output.
Behind the scenes construction of a new object in javascript prototypes from some object with a "toString" method. The default object provides this method as a property, and that method internally invokes the tag to determine how to coerce the object to a string. If the tag is present, then it's used, if missing you get "Object".
Should you set Symbol.toStringTag? Maybe. But relying on the string always being [object Object] for "true" objects is not the best idea.
The object whose class is Object seems quite different from the usual class instance object, because it acts like an associative array or list: it can be created by simple object literals (a list of keys and properties), like this: let obj={A:'a',B:'b'}; and because it looks very like this same literal notation when displayed in the Developer Tools Console pane and when it is converted to a JSON string.
But, in fact, the only real difference in objects of other classes (which are derived or extended from Object) is that other classes usually have constructors and methods (these are all functions), in addition to properties (which are variables). A class instance object is allocated using the 'new' operator, and its properties and methods are accessible through the 'this' variable. You can also access the underlying static functions that are copied to each new instance by using the 'prototype' property, and even extend system classes by adding new functions to their prototype object.
The Array object is also derived from Object and is frequently used: it is an ordered, 0-indexed array of variable values.
Object objects, unlike Arrays and other classes are treated simply as associative arrays (sometimes considered ordered, and sometimes considered unordered).

How to fetch key and value from javascript object using Object.entries? [duplicate]

I am trying to alert a returned value from a function and I get this in the alert:
[object Object]
Here is the JavaScript code:
<script type="text/javascript">
$(function ()
{
var $main = $('#main'),
$1 = $('#1'),
$2 = $('#2');
$2.hide(); // hide div#2 when the page is loaded
$main.click(function ()
{
$1.toggle();
$2.toggle();
});
$('#senddvd').click(function ()
{
alert('hello');
var a=whichIsVisible();
alert(whichIsVisible());
});
function whichIsVisible()
{
if (!$1.is(':hidden')) return $1;
if (!$2.is(':hidden')) return $2;
}
});
</script>
whichIsVisible is the function which I am trying to check on.
As others have noted, this is the default serialisation of an object. But why is it [object Object] and not just [object]?
That is because there are different types of objects in Javascript!
Function objects:
stringify(function (){}) -> [object Function]
Array objects:
stringify([]) -> [object Array]
RegExp objects
stringify(/x/) -> [object RegExp]
Date objects
stringify(new Date) -> [object Date]
… several more …
and Object objects!
stringify({}) -> [object Object]
That's because the constructor function is called Object (with a capital "O"), and the term "object" (with small "o") refers to the structural nature of the thingy.
Usually, when you're talking about "objects" in Javascript, you actually mean "Object objects", and not the other types.
where stringify should look like this:
function stringify (x) {
console.log(Object.prototype.toString.call(x));
}
The default conversion from an object to string is "[object Object]".
As you are dealing with jQuery objects, you might want to do
alert(whichIsVisible()[0].id);
to print the element's ID.
As mentioned in the comments, you should use the tools included in browsers like Firefox or Chrome to introspect objects by doing console.log(whichIsVisible()) instead of alert.
Sidenote: IDs should not start with digits.
[object Object] is the default toString representation of an object in javascript.
If you want to know the properties of your object, just foreach over it like this:
for(var property in obj) {
alert(property + "=" + obj[property]);
}
In your particular case, you are getting a jQuery object. Try doing this instead:
$('#senddvd').click(function ()
{
alert('hello');
var a=whichIsVisible();
alert(whichIsVisible().attr("id"));
});
This should alert the id of the visible element.
You can see value inside [object Object] like this
Alert.alert( JSON.stringify(userDate) );
Try like this
realm.write(() => {
const userFormData = realm.create('User',{
user_email: value.username,
user_password: value.password,
});
});
const userDate = realm.objects('User').filtered('user_email == $0', value.username.toString(), );
Alert.alert( JSON.stringify(userDate) );
reference
https://off.tokyo/blog/react-native-object-object/
Basics
You may not know it but, in JavaScript, whenever we interact with string, number or boolean primitives we enter a hidden world of object shadows and coercion.
string, number, boolean, null, undefined, and symbol.
In JavaScript there are 7 primitive types: undefined, null, boolean, string, number, bigint and symbol. Everything else is an object. The primitive types boolean, string and number can be wrapped by their object counterparts. These objects are instances of the Boolean, String and Number constructors respectively.
typeof true; //"boolean"
typeof new Boolean(true); //"object"
typeof "this is a string"; //"string"
typeof new String("this is a string"); //"object"
typeof 123; //"number"
typeof new Number(123); //"object"
If primitives have no properties, why does "this is a string".length return a value?
Because JavaScript will readily coerce between primitives and objects. In this case the string value is coerced to a string object in order to access the property length. The string object is only used for a fraction of second after which it is sacrificed to the Gods of garbage collection – but in the spirit of the TV discovery shows, we will trap the elusive creature and preserve it for further analysis…
To demonstrate this further consider the following example in which we are adding a new property to String constructor prototype.
String.prototype.sampleProperty = 5;
var str = "this is a string";
str.sampleProperty; // 5
By this means primitives have access to all the properties (including methods) defined by their respective object constructors.
So we saw that primitive types will appropriately coerce to their respective Object counterpart when required.
Analysis of toString() method
Consider the following code
var myObj = {lhs: 3, rhs: 2};
var myFunc = function(){}
var myString = "This is a sample String";
var myNumber = 4;
var myArray = [2, 3, 5];
myObj.toString(); // "[object Object]"
myFunc.toString(); // "function(){}"
myString.toString(); // "This is a sample String"
myNumber.toString(); // "4"
myArray.toString(); // "2,3,5"
As discussed above, what's really happening is when we call toString() method on a primitive type, it has to be coerced into its object counterpart before it can invoke the method.
i.e. myNumber.toString() is equivalent to Number.prototype.toString.call(myNumber) and similarly for other primitive types.
But what if instead of primitive type being passed into toString() method of its corresponding Object constructor function counterpart, we force the primitive type to be passed as parameter onto toString() method of Object function constructor (Object.prototype.toString.call(x))?
Closer look at Object.prototype.toString()
As per the documentation,
When the toString method is called, the following steps are taken:
If the this value is undefined, return "[object Undefined]".
If the this value is null, return "[object Null]".
If this value is none of the above, Let O be the result of calling toObject passing the this value as the argument.
Let class be the value of the [[Class]] internal property of O.
Return the String value that is the result of concatenating the three Strings "[object ", class, and "]".
Understand this from the following example
var myObj = {lhs: 3, rhs: 2};
var myFunc = function(){}
var myString = "This is a sample String";
var myNumber = 4;
var myArray = [2, 3, 5];
var myUndefined = undefined;
var myNull = null;
Object.prototype.toString.call(myObj); // "[object Object]"
Object.prototype.toString.call(myFunc); // "[object Function]"
Object.prototype.toString.call(myString); // "[object String]"
Object.prototype.toString.call(myNumber); // "[object Number]"
Object.prototype.toString.call(myArray); // "[object Array]"
Object.prototype.toString.call(myUndefined); // "[object Undefined]"
Object.prototype.toString.call(myNull); // "[object Null]"
References:
https://es5.github.io/x15.2.html#x15.2.4.2
https://es5.github.io/x9.html#x9.9
https://javascriptweblog.wordpress.com/2010/09/27/the-secret-life-of-javascript-primitives/
It's the value returned by that object's toString() function.
I understand what you're trying to do, because I answered your question yesterday about determining which div is visible. :)
The whichIsVisible() function returns an actual jQuery object, because I thought that would be more programmatically useful. If you want to use this function for debugging purposes, you can just do something like this:
function whichIsVisible_v2()
{
if (!$1.is(':hidden')) return '#1';
if (!$2.is(':hidden')) return '#2';
}
That said, you really should be using a proper debugger rather than alert() if you're trying to debug a problem. If you're using Firefox, Firebug is excellent. If you're using IE8, Safari, or Chrome, they have built-in debuggers.
[object Object] is the default string representation of a JavaScript Object. It is what you'll get if you run this code:
alert({}); // [object Object]
You can change the default representation by overriding the toString method like so:
var o = {toString: function(){ return "foo" }};
alert(o); // foo
I think the best way out is by using JSON.stringify() and passing your data as param:
alert(JSON.stringify(whichIsVisible()));
You have a javascript object
$1 and $2 are jquery objects, maybe use alert($1.text()); to get text or alert($1.attr('id'); etc...
you have to treat $1 and $2 like jQuery objects.
You are trying to return an object. Because there is no good way to represent an object as a string, the object's .toString() value is automatically set as "[object Object]".
Consider the following example:
const foo = {};
foo[Symbol.toStringTag] = "bar";
console.log("" + foo);
Which outputs
[object bar]
Basically, any object in javascript can define a property with the tag Symbol.toStringTag and override the output.
Behind the scenes construction of a new object in javascript prototypes from some object with a "toString" method. The default object provides this method as a property, and that method internally invokes the tag to determine how to coerce the object to a string. If the tag is present, then it's used, if missing you get "Object".
Should you set Symbol.toStringTag? Maybe. But relying on the string always being [object Object] for "true" objects is not the best idea.
The object whose class is Object seems quite different from the usual class instance object, because it acts like an associative array or list: it can be created by simple object literals (a list of keys and properties), like this: let obj={A:'a',B:'b'}; and because it looks very like this same literal notation when displayed in the Developer Tools Console pane and when it is converted to a JSON string.
But, in fact, the only real difference in objects of other classes (which are derived or extended from Object) is that other classes usually have constructors and methods (these are all functions), in addition to properties (which are variables). A class instance object is allocated using the 'new' operator, and its properties and methods are accessible through the 'this' variable. You can also access the underlying static functions that are copied to each new instance by using the 'prototype' property, and even extend system classes by adding new functions to their prototype object.
The Array object is also derived from Object and is frequently used: it is an ordered, 0-indexed array of variable values.
Object objects, unlike Arrays and other classes are treated simply as associative arrays (sometimes considered ordered, and sometimes considered unordered).

How to Pass object to url parameter and then get it [duplicate]

I am trying to alert a returned value from a function and I get this in the alert:
[object Object]
Here is the JavaScript code:
<script type="text/javascript">
$(function ()
{
var $main = $('#main'),
$1 = $('#1'),
$2 = $('#2');
$2.hide(); // hide div#2 when the page is loaded
$main.click(function ()
{
$1.toggle();
$2.toggle();
});
$('#senddvd').click(function ()
{
alert('hello');
var a=whichIsVisible();
alert(whichIsVisible());
});
function whichIsVisible()
{
if (!$1.is(':hidden')) return $1;
if (!$2.is(':hidden')) return $2;
}
});
</script>
whichIsVisible is the function which I am trying to check on.
As others have noted, this is the default serialisation of an object. But why is it [object Object] and not just [object]?
That is because there are different types of objects in Javascript!
Function objects:
stringify(function (){}) -> [object Function]
Array objects:
stringify([]) -> [object Array]
RegExp objects
stringify(/x/) -> [object RegExp]
Date objects
stringify(new Date) -> [object Date]
… several more …
and Object objects!
stringify({}) -> [object Object]
That's because the constructor function is called Object (with a capital "O"), and the term "object" (with small "o") refers to the structural nature of the thingy.
Usually, when you're talking about "objects" in Javascript, you actually mean "Object objects", and not the other types.
where stringify should look like this:
function stringify (x) {
console.log(Object.prototype.toString.call(x));
}
The default conversion from an object to string is "[object Object]".
As you are dealing with jQuery objects, you might want to do
alert(whichIsVisible()[0].id);
to print the element's ID.
As mentioned in the comments, you should use the tools included in browsers like Firefox or Chrome to introspect objects by doing console.log(whichIsVisible()) instead of alert.
Sidenote: IDs should not start with digits.
[object Object] is the default toString representation of an object in javascript.
If you want to know the properties of your object, just foreach over it like this:
for(var property in obj) {
alert(property + "=" + obj[property]);
}
In your particular case, you are getting a jQuery object. Try doing this instead:
$('#senddvd').click(function ()
{
alert('hello');
var a=whichIsVisible();
alert(whichIsVisible().attr("id"));
});
This should alert the id of the visible element.
You can see value inside [object Object] like this
Alert.alert( JSON.stringify(userDate) );
Try like this
realm.write(() => {
const userFormData = realm.create('User',{
user_email: value.username,
user_password: value.password,
});
});
const userDate = realm.objects('User').filtered('user_email == $0', value.username.toString(), );
Alert.alert( JSON.stringify(userDate) );
reference
https://off.tokyo/blog/react-native-object-object/
Basics
You may not know it but, in JavaScript, whenever we interact with string, number or boolean primitives we enter a hidden world of object shadows and coercion.
string, number, boolean, null, undefined, and symbol.
In JavaScript there are 7 primitive types: undefined, null, boolean, string, number, bigint and symbol. Everything else is an object. The primitive types boolean, string and number can be wrapped by their object counterparts. These objects are instances of the Boolean, String and Number constructors respectively.
typeof true; //"boolean"
typeof new Boolean(true); //"object"
typeof "this is a string"; //"string"
typeof new String("this is a string"); //"object"
typeof 123; //"number"
typeof new Number(123); //"object"
If primitives have no properties, why does "this is a string".length return a value?
Because JavaScript will readily coerce between primitives and objects. In this case the string value is coerced to a string object in order to access the property length. The string object is only used for a fraction of second after which it is sacrificed to the Gods of garbage collection – but in the spirit of the TV discovery shows, we will trap the elusive creature and preserve it for further analysis…
To demonstrate this further consider the following example in which we are adding a new property to String constructor prototype.
String.prototype.sampleProperty = 5;
var str = "this is a string";
str.sampleProperty; // 5
By this means primitives have access to all the properties (including methods) defined by their respective object constructors.
So we saw that primitive types will appropriately coerce to their respective Object counterpart when required.
Analysis of toString() method
Consider the following code
var myObj = {lhs: 3, rhs: 2};
var myFunc = function(){}
var myString = "This is a sample String";
var myNumber = 4;
var myArray = [2, 3, 5];
myObj.toString(); // "[object Object]"
myFunc.toString(); // "function(){}"
myString.toString(); // "This is a sample String"
myNumber.toString(); // "4"
myArray.toString(); // "2,3,5"
As discussed above, what's really happening is when we call toString() method on a primitive type, it has to be coerced into its object counterpart before it can invoke the method.
i.e. myNumber.toString() is equivalent to Number.prototype.toString.call(myNumber) and similarly for other primitive types.
But what if instead of primitive type being passed into toString() method of its corresponding Object constructor function counterpart, we force the primitive type to be passed as parameter onto toString() method of Object function constructor (Object.prototype.toString.call(x))?
Closer look at Object.prototype.toString()
As per the documentation,
When the toString method is called, the following steps are taken:
If the this value is undefined, return "[object Undefined]".
If the this value is null, return "[object Null]".
If this value is none of the above, Let O be the result of calling toObject passing the this value as the argument.
Let class be the value of the [[Class]] internal property of O.
Return the String value that is the result of concatenating the three Strings "[object ", class, and "]".
Understand this from the following example
var myObj = {lhs: 3, rhs: 2};
var myFunc = function(){}
var myString = "This is a sample String";
var myNumber = 4;
var myArray = [2, 3, 5];
var myUndefined = undefined;
var myNull = null;
Object.prototype.toString.call(myObj); // "[object Object]"
Object.prototype.toString.call(myFunc); // "[object Function]"
Object.prototype.toString.call(myString); // "[object String]"
Object.prototype.toString.call(myNumber); // "[object Number]"
Object.prototype.toString.call(myArray); // "[object Array]"
Object.prototype.toString.call(myUndefined); // "[object Undefined]"
Object.prototype.toString.call(myNull); // "[object Null]"
References:
https://es5.github.io/x15.2.html#x15.2.4.2
https://es5.github.io/x9.html#x9.9
https://javascriptweblog.wordpress.com/2010/09/27/the-secret-life-of-javascript-primitives/
It's the value returned by that object's toString() function.
I understand what you're trying to do, because I answered your question yesterday about determining which div is visible. :)
The whichIsVisible() function returns an actual jQuery object, because I thought that would be more programmatically useful. If you want to use this function for debugging purposes, you can just do something like this:
function whichIsVisible_v2()
{
if (!$1.is(':hidden')) return '#1';
if (!$2.is(':hidden')) return '#2';
}
That said, you really should be using a proper debugger rather than alert() if you're trying to debug a problem. If you're using Firefox, Firebug is excellent. If you're using IE8, Safari, or Chrome, they have built-in debuggers.
[object Object] is the default string representation of a JavaScript Object. It is what you'll get if you run this code:
alert({}); // [object Object]
You can change the default representation by overriding the toString method like so:
var o = {toString: function(){ return "foo" }};
alert(o); // foo
I think the best way out is by using JSON.stringify() and passing your data as param:
alert(JSON.stringify(whichIsVisible()));
You have a javascript object
$1 and $2 are jquery objects, maybe use alert($1.text()); to get text or alert($1.attr('id'); etc...
you have to treat $1 and $2 like jQuery objects.
You are trying to return an object. Because there is no good way to represent an object as a string, the object's .toString() value is automatically set as "[object Object]".
Consider the following example:
const foo = {};
foo[Symbol.toStringTag] = "bar";
console.log("" + foo);
Which outputs
[object bar]
Basically, any object in javascript can define a property with the tag Symbol.toStringTag and override the output.
Behind the scenes construction of a new object in javascript prototypes from some object with a "toString" method. The default object provides this method as a property, and that method internally invokes the tag to determine how to coerce the object to a string. If the tag is present, then it's used, if missing you get "Object".
Should you set Symbol.toStringTag? Maybe. But relying on the string always being [object Object] for "true" objects is not the best idea.
The object whose class is Object seems quite different from the usual class instance object, because it acts like an associative array or list: it can be created by simple object literals (a list of keys and properties), like this: let obj={A:'a',B:'b'}; and because it looks very like this same literal notation when displayed in the Developer Tools Console pane and when it is converted to a JSON string.
But, in fact, the only real difference in objects of other classes (which are derived or extended from Object) is that other classes usually have constructors and methods (these are all functions), in addition to properties (which are variables). A class instance object is allocated using the 'new' operator, and its properties and methods are accessible through the 'this' variable. You can also access the underlying static functions that are copied to each new instance by using the 'prototype' property, and even extend system classes by adding new functions to their prototype object.
The Array object is also derived from Object and is frequently used: it is an ordered, 0-indexed array of variable values.
Object objects, unlike Arrays and other classes are treated simply as associative arrays (sometimes considered ordered, and sometimes considered unordered).

adding properties to primitive data types other than Array

I'm not supposed to add elements to an array like this:
var b = [];
b.val_1 = "a";
b.val_2 = "b";
b.val_3 = "c";
I can't use native array methods and why not just an object. I'm just adding properties to the array, not elements. I suppose this makes them parallel to the length property. Though trying to reset length (b.length = "a string") gets Uncaught RangeError: Invalid array length.
In any case, I can still see the properties I've set like this:
console.log(b); //[val_1: "a", val_2: "b", val_3: "c"]
I can access it using the dot syntax:
console.log(b.val_1); //a
If an array is just an object in the same way a string or a number is an object, why can't (not that I'd want to) I attach properties to them with this syntax:
var num = 1;
num.prop_1 = "a string";
console.log(num); //1
I cannot access its properties using dot syntax
console.log(num.prp); //undefined
Why can this be done with array and not with other datatypes. For all cases, I should use {} and would only ever need to use {}, so why have arrays got this ability?
JSBIN
Because arrays are treated as Objects by the language, you can see this by typing the following line of code:
console.log(typeof []) // object
But other types like number literals, string literals NaN ... etc are primitive types and are only wrapped in their object reprsentation in certain contexts defined by the language.
If you want to add properties or methods to a number like that, then you can use the Number constructor like this:
var num = new Number(1);
num.prop_1 = "fdadsf";
console.log(num.prop_1);
Using the Number constructor returns a number object which you can see by typing the following line:
console.log(typeof num); // object
While in the first case:
var num = 1;
console.log(typeof num) // number
EDIT 2: When you invoke a method on a number literal or string literal for instance, then that primitive is wrapped into its object representation automatically by the language for the method call to take place, for example:
var num = 3;
console.log(num.toFixed(3)); // 3.000
Here num is a primitive variable, but when you call the toFixed() metohd on it, it gets wrapped to a Number object so the method call can take place.
EDIT: In the first case, you created a string like this first var str = new String(), but then you changed it to str = "asdf" and then assigned the property str.var_1 = "1234".
Of course, this won't work, because when you assigned str = "asdf", str became a primitive type and the Object instance that was originally created is now gone, and you can't add properties to primitives.
In the second, it didn't output undefined like you said, I tested it in Firebug and everything worked correctly.
EDIT 3:
String literals (denoted by double or single quotes) and strings returned from String calls in a non-constructor context (i.e., without using the new keyword) are primitive strings.
This is taken from MDN Documentation, when you use string like that var p = String(3) it becomes a conversion function and not a constructor and it returns a primitive string as you can see from the quote above.
Regarding your second comment, I didn't understand how my comment has been defied, because if you try to console.log(p.pr) you'll get undefined which proves p is a primitive type and not an object.
If an array is just an object in the same way a string or a number is an object,
An array is different than strings, numbers, booleans, null and undefined. An array IS an object, while the others in the list are primitive values. You can add properties to the array just like you would with any other object, anything different being just what makes arrays special (the length property you mentioned for example). You cannot add properties or call methods on primitive values.
In this previous answer i talked about the use of Object wrappers over primitive values. Feel free to read it to see more about Object wrappers. The following will be a very short example:
console.log('TEST'.toLowerCase()) // 'test'
While it may seem that the toLowerCase method is called on the string 'TEST', in fact the string is converted automatically to a String object and the toLowerCase method is called on the String object.
Each time a property of the string, number or boolean is called, a new Object wrapper of the apropriate type is created to get or set that value (setting properties might be optimized away entirely by the browser, i am not sure about that).
As per your example:
var num = 1; // primitive value
num.prop_1 = "a string"; // num is converted to a Number, the prop_1 property is set on the Object which is discarded immediately afterwards
console.log(num); //1 // primitive value
console.log(num.prp); // num is converted to a Number, which doesn't have the prp property
My example:
Number.prototype.myProp = "works!";
String.prototype.myFunc = function() { return 'Test ' + this.valueOf() };
Boolean.prototype.myTest = "Done";
console.log(true.myTest); // 'Done'
console.log('really works!'.myFunc()); // 'Test really works!'
var x = 3;
console.log(x.myProp.myFunc()); // 'Test works!'
console.log(3['myProp']); // 'works!'
On the other hand:
console.log(3.myProp); // SyntaxError: Unexpected token ILLEGAL
The number isn't necessarily treated differently, that syntax just confuses the parser. The following example should work:
console.log(3.0.myProp); // 'works!'

Primitives and Objects

Definitive JavaScript by David Flanagan makes a distinction between Objects and Primitives.
He defines the primitives as Number, String, Boolean, Null, and Undefined, as does the standard.
However, would it be more accurate to define a primitive, as subset of object, i.e. to call them Primitive Objects.
Because they have their own methods and are complex entities.
Actual Question
Would Primitive Object be more accurate than Object when defining String, Boolean, and Number?
Objects and primitives are distinct:
typeof 42 === "number"
typeof new Number(42) === "object"
new Number(42) !== 42
However, when necessary, primitives are automatically wrapped by temporary objects, which can be automatically converted back into primitives:
(42).toString() === "42"
new Number(42) == 42
new Number(42) + 1 === 43
Especially in the context of the Java and C# programming languages, this sort of behavior is called autoboxing. As wrapper objects have some confusing characteristics, for example:
Boolean(new Boolean(false)) === true
it is good practice to avoid intentionally storing them in variables and instead use primitives whenever possible.
It's not about semantics, look:
var threePrimitive = 3;
var threeObject = new Number(3);
threePrimitive.toFixed(2); // 3.00
threeObject.toFixed(2); // 3.00
threePrimitive.foo = true
threeObject.foo = true;
threePrimitive.foo; // undefined
threeObject.foo; // true
Primitives are wrapped in objects when you try to call a method on them, but after initial use the object is thrown away.
As for how this is stated in the specification, I'm not 100% sure, but here is what I think (based on the tips left by Bergi in one of his answers. Section 11.2.1 states that the accessor properties should be evaluated as follows:
Let baseReference be the result of evaluating MemberExpression.
Let baseValue be GetValue(baseReference).
(...)
Then in 8.7.1 we see the following:
The following [[Get]] internal method is used by GetValue when V is a
property reference with a primitive base value. It is called using
base as its this value and with property P as its argument. The
following steps are taken:
Let O be ToObject(base).
Let desc be the result of calling the
[[GetProperty]] internal method of O with property name P.
If desc is
undefined, return undefined.
If IsDataDescriptor(desc) is true, return
desc.[[Value]].
Otherwise, IsAccessorDescriptor(desc) must be true so,
let getter be desc.[[Get]]. If getter is undefined, return undefined.
Return the result calling the [[Call]] internal method of getter
providing base as the this value and providing no arguments.
NOTE The
object that may be created in step 1 is not accessible outside of the
above method. An implementation might choose to avoid the actual
creation of the object. The only situation where such an actual
property access that uses this internal method can have visible effect
is when it invokes an accessor function.
Would Primitive Object be more accurate then Object when defining
String, Boolean, and Number?
Please note that I'm not saying that numbers are not objects here, I'm pointing out that it appears ambiguous. This is the kind of thing that confuses JavaScript newcomers.
The distinction is mostly academic, but there is one case where it seems ambiguous: literals represent primitive objects except when the literal appears to represent a number. You can't apply a method directly to a literal integer* symbol:
1.toString();
SyntaxError: identifier starts immediately after numeric literal
…but you can apply methods of Numbers:
Number(1).toString();
'1'
…and a name that contains a number is a Number:
x = 4;
x.toString();
'4'
I think this is actually a parsing problem, but I don't really know why the parser can't tell that 1 is a Number as easily as it can tell that "abc" is a String. I suppose it has to do with the semantic ambiguity of the . symbol. (Is it a decimal point or a method operator?)
*JavaScript doesn't actually have integers. I just mean a symbol that consists entirely of [0-9]+.

Categories

Resources