Javascript object inheritance not showing expected result - javascript

I used to think that both assignments a = "foo" and a = new String('foo') are the same things. But with the former declaration, console.log(a instanceof Object) or console.log(a instanceof String) returns false, while it returns the expected true for the latter.
This seems weird for two reasons. Firstly, even with the normal declaration a = 'foo', all string methods work on it, suggesting that it has inherited from String object. And secondly, a.constructor returns String.
Can anybody explain what's going on?

"foo" is a primitive literal.
But new String("foo") is an instance of the class String.
You can call methods on the primitive value because
JavaScript automatically converts primitives to String objects, so
that it's possible to use String object methods for primitive strings. In contexts where a method is to be invoked on a primitive string or a property lookup occurs, JavaScript will automatically wrap the string primitive and call the method or perform the property lookup.
(from the MDN)

Related

Extra Object in prototype chain of Number object [duplicate]

I read this a lot in many JavaScript introductions. I just don't understand it. I always think of objects as something with methods and properties.
Arrays I understand, since it has key value pair.
How about "Strings" or "Numbers" or "functions" ?
These things above listed seem to be like functions to me. This means you input something, you get something out. You don't really get the access properties or anything. There's no dot notation used in arrays or this list of "objects".
Does anyone code some examples of each of these with dot notations which its methods and properties are being accessed? I suspect that definition of object is probably limited since I did start learning about JavaScript...
No, not everything is an object in JavaScript. Many things that you interact with regularly (strings, numbers, booleans) are primitives, not objects. Unlike objects, primitive values are immutable. The situation is complicated by the fact that these primitives do have object wrappers (String, Number and Boolean); these objects have methods and properties while the primitives do not, but the primitives appear to have methods because JavaScript silently creates a wrapper object when code attempts to access any property of a primitive.
For example, consider the following code:
var s = "foo";
var sub = s.substring(1, 2); // sub is now the string "o"
Behind the scenes, s.substring(1, 2) behaves as if it is performing the following (approximate) steps:
Create a wrapper String object from s, equivalent to using new String(s)
Call the substring() method with the appropriate parameters on the String object returned by step 1
Dispose of the String object
Return the string (primitive) from step 2.
A consequence of this is that while it looks as though you can assign properties to primitives, it is pointless because you cannot retrieve them:
var s = "foo";
s.bar = "cheese";
alert(s.bar); // undefined
This happens because the property is effectively defined on a String object that is immediately discarded.
Numbers and Booleans also behave this way. Functions, however, are fully-fledged objects, and inherit from Object (actually Object.prototype, but that's another topic). Functions therefore can do anything objects can, including having properties:
function foo() {}
foo.bar = "tea";
alert(foo.bar); // tea
That’s right: in JavaScript, almost everything is an object. But these objects are bit different from what we see in Java, C++ or other conventional languages. An object in JS is simply a hashmap with key–value pairs. A key is always a string or a symbol, and a value can be anything including strings, integers, booleans, functions, other objects etc. So I can create a new object like this:
var obj = {}; // This is not the only way to create an object in JS
and add new key–value pairs into it:
obj['message'] = 'Hello'; // You can always attach new properties to an object externally
or
obj.message = 'Hello';
Similarly, if I want to add a new function to this object:
obj['showMessage'] = function(){
alert(this['message']);
}
or
obj.showMessage = function() {
alert(this.message);
}
Now, whenever I call this function, it will show a pop-up with a message:
obj.showMessage();
Arrays are simply those objects which are capable of containing lists of values:
var arr = [32, 33, 34, 35]; // One way of creating arrays in JS
Although you can always use any object to store values, but arrays allow you to store them without associating a key with each of them. So you can access an item using its index:
alert(arr[1]); // This would show 33
An array object, just like any other object in JS, has its properties, such as:
alert(arr.length); // This would show 4
For in-depth detail, I would highly recommend John Resig’s Pro JavaScript Techniques.
The sentence "In JavaScript, ALMOST everything is an object" is correct, because the MAIN code-units (objects, functions, arrays) are JavaScript-objects.
JavaScript code uses 9 different-units plus 1 (multiple):
- 01. array
- 02. boolean
- 03. function
- 04. null
- 05. number
- 06. object
- 07. regexp
- 08. string
- 09. undefined
- 10. multiple
BUT JavaScript-objects:
- are NOT same creatures as the 'objects' in other object-oriented-languages.
- they are a collection of name-value-pairs.
- all have a function of creation (its constructor).
- all INHERIT the members of the prototype-object of its constructor and this is its prototype.
- all functions are objects BUT NOT all objects are functions.
- functions have scope, objects NOT (a design flaw in my opinion).
- Object, Function, Array, String, ... with first CAPITAL are functions!!!
- it is more important the differences of JS objects and functions, than its commonnesses.
- the name 'instance' in JS has different meaning with the name 'instance' in knowledge-theory where an instance inherits the attributes of its generic-concept. In JS denotes only its constructor. JavaScript got the name 'instance' from 'class-based-inheritance' ool (java) where it is an appropriate name because those objects inherit the attributes of classes.
A better name for the JS-keyword 'instanceof' is 'objectof'.
JS-functions ARE JS-objects because:
1) they can have members like JS-objects:
> function f(){}
undefined
> f.s = "a string"
"a string"
> f.s
"a string"
2) they have a constructor-function, like all JS-objects, the Function function:
> (function f(){}) instanceof Function
true
3) as all JS-objects, their prototype-object is the same with its constructor prototype:
> (function f(){}).__proto__ === Function.prototype
true
> ({}).__proto__ === Object.prototype
true
> (new Object).__proto__ === Object.prototype
true
4) of course, JS-functions as SPECIFIC JS-objects have and extra attributes, like all functions in programming-languages, that JS-objects do not have like you can call (execute) them with input and output information.
EVERYTHING is NOT an object, because, for example, we can NOT add members to a literal string:
> var s = "string"
undefined
> s.s2 = "s2string"
"s2string"
> s.s2
undefined
Based on developer.mozilla.org and also ECMAScript specification the answer is no. Technically not everything is object.
https://developer.mozilla.org/en-US/docs/Glossary/Primitive
In JavaScript, a primitive (primitive value, primitive data type) is data that is not an object and has no methods. There are 7 primitive data types: string, number, bigint, boolean, null, undefined, symbol
A primitive is not an object and has no methods and It is also immutable. Except for null and undefined, all the other primitive have a wrap object around them to provide you some functions that you can use. For example String for the string primitive.
https://developer.mozilla.org/en-US/docs/Glossary/Primitive#Primitive_wrapper_objects_in_JavaScript
So here in the following code when you call toUpperCase() on a primitive data name JavaScript will automatically wrap the string primitive and call toUpperCase function of String object
var name = 'Tom';
console.log(name);
name.toUpperCase();
console.log(name);
In contexts where a method is to be invoked on a primitive string or a property lookup occurs, JavaScript will automatically wrap the string primitive and call the method or perform the property lookup.
Also note that JavaScript distinguishes between String objects and primitive string values.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#Distinction_between_string_primitives_and_String_objects
var nameP = 'Tom';
var nameO = new String(nameP);
typeof nameP // "string"
typeof nameO // "object"
Not everything is an object in javaScript. JavaScript has primitives and objects.
There are six primitives-null,undefined,string,number,boolean and symbol.
It might seem like everything is acting as an object because of the properties and function that can be accessed.for example-
var stringvar="this string";
typeof stringvar; // "string"
stringvar.length; //11
now since "stringvar" is a string type ,which is a primitive type,it should not be able to accesss property length.It can do so because of something called Boxing.Boxing is the process where any primitive type is converted to an Object type and the reverse is called Unboxing.These object types or Object wrappers are created with the view that there are some common operations that one might need to perform with the primitive values.They contain useful methods and properties and are prototype linked to the primitives.
As far as the Objects are concerned,key value pairs can be added to every object,even to the arrays.
var arr=[1,2,3];
arr.name="my array";
arr; //[1,2,3,name:'my array']
this does not mean that the fourth element of the array is "name:'my array'"."name" is a property that can be called with dot notation(arr.name) or brackets notation(arr["name"]).
I would say "Everything in Javascript is not an object (because of primitives) but everything in javascript leads back to an object (because of wrappers and Object constructor)"

Difference in these 2 Strings (JavaScript)

I was trying to create string data-types variables with values in 2 ways.
As string-literal
Using New Keyword
But to me it seems that these both are different in representation on console.log.
Can someone tell me if 2nd way doesn't return string or is it someway different?
var str1 = "abc";
var str2 = new String("def");
console.log(str1);
console.log(str2);
Expected:
abc, def
Output:
JavaScript has two main type categories, primivites and objects.
typeof new String(); // "object"
typeof ''; // "string"
For statements of assigning primitive values to a variable like:
var str1 = "Hi";
JavaScript will internally create the variable using:
String("Hi")
Using the new keyword works differently and returns an object instead.
Calling new String(something) makes a String instance object.
The results look the same via console.log() because it'll just extract the primitive string from the String instance you pass to it.
So: just plain String() returns a string primitive. new String('xyz') returns an object constructed by the String constructor.
It's rarely necessary to explicitly construct a String instance.
You are working with two different things.
The var str1 = "abc" gives you a primitive.
While the var str2 = new String("def"); gives you a string object.
These two types behave differently
The String object lets you work with a series of characters; it wraps Javascript's string primitive data type with a number of helper methods.
As JavaScript automatically converts between string primitives and String objects, you can call any of the helper methods of the String object on a string primitive.
When you print an object, often the console print the object's properties.
If is a primitive the console just print the value.
The primitive is not boxed, but if you create a string with a constructor the string is boxed in the object and always have properties.
If is just a literal, it only have properties when you access to a string's property with . operator because boxing occurs, but after that, it still being a literal with nothing additional added, because of that when you print "The cat is very grumpy", just print the value and nothing more. primitives literals are not always objects with properties, are only objects when are boxed.

A Function that can be an Object in JavaScript? [duplicate]

I read this a lot in many JavaScript introductions. I just don't understand it. I always think of objects as something with methods and properties.
Arrays I understand, since it has key value pair.
How about "Strings" or "Numbers" or "functions" ?
These things above listed seem to be like functions to me. This means you input something, you get something out. You don't really get the access properties or anything. There's no dot notation used in arrays or this list of "objects".
Does anyone code some examples of each of these with dot notations which its methods and properties are being accessed? I suspect that definition of object is probably limited since I did start learning about JavaScript...
No, not everything is an object in JavaScript. Many things that you interact with regularly (strings, numbers, booleans) are primitives, not objects. Unlike objects, primitive values are immutable. The situation is complicated by the fact that these primitives do have object wrappers (String, Number and Boolean); these objects have methods and properties while the primitives do not, but the primitives appear to have methods because JavaScript silently creates a wrapper object when code attempts to access any property of a primitive.
For example, consider the following code:
var s = "foo";
var sub = s.substring(1, 2); // sub is now the string "o"
Behind the scenes, s.substring(1, 2) behaves as if it is performing the following (approximate) steps:
Create a wrapper String object from s, equivalent to using new String(s)
Call the substring() method with the appropriate parameters on the String object returned by step 1
Dispose of the String object
Return the string (primitive) from step 2.
A consequence of this is that while it looks as though you can assign properties to primitives, it is pointless because you cannot retrieve them:
var s = "foo";
s.bar = "cheese";
alert(s.bar); // undefined
This happens because the property is effectively defined on a String object that is immediately discarded.
Numbers and Booleans also behave this way. Functions, however, are fully-fledged objects, and inherit from Object (actually Object.prototype, but that's another topic). Functions therefore can do anything objects can, including having properties:
function foo() {}
foo.bar = "tea";
alert(foo.bar); // tea
That’s right: in JavaScript, almost everything is an object. But these objects are bit different from what we see in Java, C++ or other conventional languages. An object in JS is simply a hashmap with key–value pairs. A key is always a string or a symbol, and a value can be anything including strings, integers, booleans, functions, other objects etc. So I can create a new object like this:
var obj = {}; // This is not the only way to create an object in JS
and add new key–value pairs into it:
obj['message'] = 'Hello'; // You can always attach new properties to an object externally
or
obj.message = 'Hello';
Similarly, if I want to add a new function to this object:
obj['showMessage'] = function(){
alert(this['message']);
}
or
obj.showMessage = function() {
alert(this.message);
}
Now, whenever I call this function, it will show a pop-up with a message:
obj.showMessage();
Arrays are simply those objects which are capable of containing lists of values:
var arr = [32, 33, 34, 35]; // One way of creating arrays in JS
Although you can always use any object to store values, but arrays allow you to store them without associating a key with each of them. So you can access an item using its index:
alert(arr[1]); // This would show 33
An array object, just like any other object in JS, has its properties, such as:
alert(arr.length); // This would show 4
For in-depth detail, I would highly recommend John Resig’s Pro JavaScript Techniques.
The sentence "In JavaScript, ALMOST everything is an object" is correct, because the MAIN code-units (objects, functions, arrays) are JavaScript-objects.
JavaScript code uses 9 different-units plus 1 (multiple):
- 01. array
- 02. boolean
- 03. function
- 04. null
- 05. number
- 06. object
- 07. regexp
- 08. string
- 09. undefined
- 10. multiple
BUT JavaScript-objects:
- are NOT same creatures as the 'objects' in other object-oriented-languages.
- they are a collection of name-value-pairs.
- all have a function of creation (its constructor).
- all INHERIT the members of the prototype-object of its constructor and this is its prototype.
- all functions are objects BUT NOT all objects are functions.
- functions have scope, objects NOT (a design flaw in my opinion).
- Object, Function, Array, String, ... with first CAPITAL are functions!!!
- it is more important the differences of JS objects and functions, than its commonnesses.
- the name 'instance' in JS has different meaning with the name 'instance' in knowledge-theory where an instance inherits the attributes of its generic-concept. In JS denotes only its constructor. JavaScript got the name 'instance' from 'class-based-inheritance' ool (java) where it is an appropriate name because those objects inherit the attributes of classes.
A better name for the JS-keyword 'instanceof' is 'objectof'.
JS-functions ARE JS-objects because:
1) they can have members like JS-objects:
> function f(){}
undefined
> f.s = "a string"
"a string"
> f.s
"a string"
2) they have a constructor-function, like all JS-objects, the Function function:
> (function f(){}) instanceof Function
true
3) as all JS-objects, their prototype-object is the same with its constructor prototype:
> (function f(){}).__proto__ === Function.prototype
true
> ({}).__proto__ === Object.prototype
true
> (new Object).__proto__ === Object.prototype
true
4) of course, JS-functions as SPECIFIC JS-objects have and extra attributes, like all functions in programming-languages, that JS-objects do not have like you can call (execute) them with input and output information.
EVERYTHING is NOT an object, because, for example, we can NOT add members to a literal string:
> var s = "string"
undefined
> s.s2 = "s2string"
"s2string"
> s.s2
undefined
Based on developer.mozilla.org and also ECMAScript specification the answer is no. Technically not everything is object.
https://developer.mozilla.org/en-US/docs/Glossary/Primitive
In JavaScript, a primitive (primitive value, primitive data type) is data that is not an object and has no methods. There are 7 primitive data types: string, number, bigint, boolean, null, undefined, symbol
A primitive is not an object and has no methods and It is also immutable. Except for null and undefined, all the other primitive have a wrap object around them to provide you some functions that you can use. For example String for the string primitive.
https://developer.mozilla.org/en-US/docs/Glossary/Primitive#Primitive_wrapper_objects_in_JavaScript
So here in the following code when you call toUpperCase() on a primitive data name JavaScript will automatically wrap the string primitive and call toUpperCase function of String object
var name = 'Tom';
console.log(name);
name.toUpperCase();
console.log(name);
In contexts where a method is to be invoked on a primitive string or a property lookup occurs, JavaScript will automatically wrap the string primitive and call the method or perform the property lookup.
Also note that JavaScript distinguishes between String objects and primitive string values.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#Distinction_between_string_primitives_and_String_objects
var nameP = 'Tom';
var nameO = new String(nameP);
typeof nameP // "string"
typeof nameO // "object"
Not everything is an object in javaScript. JavaScript has primitives and objects.
There are six primitives-null,undefined,string,number,boolean and symbol.
It might seem like everything is acting as an object because of the properties and function that can be accessed.for example-
var stringvar="this string";
typeof stringvar; // "string"
stringvar.length; //11
now since "stringvar" is a string type ,which is a primitive type,it should not be able to accesss property length.It can do so because of something called Boxing.Boxing is the process where any primitive type is converted to an Object type and the reverse is called Unboxing.These object types or Object wrappers are created with the view that there are some common operations that one might need to perform with the primitive values.They contain useful methods and properties and are prototype linked to the primitives.
As far as the Objects are concerned,key value pairs can be added to every object,even to the arrays.
var arr=[1,2,3];
arr.name="my array";
arr; //[1,2,3,name:'my array']
this does not mean that the fourth element of the array is "name:'my array'"."name" is a property that can be called with dot notation(arr.name) or brackets notation(arr["name"]).
I would say "Everything in Javascript is not an object (because of primitives) but everything in javascript leads back to an object (because of wrappers and Object constructor)"

Understanding the typeof operator in Javascript

I came across the following table which states the internal [[Class]] property of an object and its corresponding value that the typeof operator returns.
Value Class Type
-------------------------------------
"foo" String string
new String("foo") String object
1.2 Number number
new Number(1.2) Number object
true Boolean boolean
new Boolean(true) Boolean object
new Date() Date object
new Error() Error object
[1,2,3] Array object
new Array(1, 2, 3) Array object
new Function("") Function function
/abc/g RegExp object (function in Nitro/V8)
new RegExp("meow") RegExp object (function in Nitro/V8)
{} Object object
new Object() Object object
One thing to note here is the typeof correctly returns the primitive data types associated in Javascript.
However, it returns an object type for an array which inherits from the Array.prototype, but returns a function type for a function that is inheriting from the Function.prototype.
Given everything is an object in Javascript (including arrays, functions & primitive data type objects), I find this behaviour of the typeof operator very inconsistent.
Can someone throw some light on how the typeof operator works in reality?
This is slightly odd, idiosyncratic Javascript behaviour. It's inherited from the earliest days of Javascript and probably would not be written in such a way today.
Nonetheless, we are where we are with Javascript, so we have to deal with it!
The thing is that values in Javascript are either objects or they are primitives. This is a design decision. They cannot be anything else. The types of primitives are:
strings
numbers
booleans
symbols (from ES2015)
the special value undefined
the special value null (for which typeof also returns object)
Anything and everything else is an object. This is by design. Arrays are objects, so typeof returns object, as does every other object that is not callable (i.e. a function). See the spec for typeof.
The better question is to ask why you want to test if something is an array. You probably don't need to, especially as array-like objects such as NodeLists are not arrays but are like them in many ways.
The best solution in most cases is to call Array.from on the value supplied: then you know that it is an array.
Use typeof operator in JavaScript
'Typeof' is an operator which is used to return a string description of the type of a variable.
Example
console.log(typeof 42);
output: "number"
console.log(typeof true);
output: "boolean"

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