At one popular blog, the author asked his audience what was their “Ah ha!” moment for JavaScript and most of the people said that it was realizing that everything in JavaScript is an object.
But being new to JS and programming in general I don't quite get what that means. It doesn't seam like it's related to actual JS Object - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
Or it does?
If it doesn't could you please explain what do they mean by "everything in JavaScript is an object".
Or it's all about OO Programming in general and reading something on this subject will help to understand it? Can you recommend what to read on this topic?
Go back to first principles.
What's an object? It's a software component that encapsulates state and behavior together into a single entity in memory.
By that definition, you can see where everything can be thought of as an object. Functional programmers make functions first class objects. Data folks would say that data, even that without behavior, can be thought of as an object (albeit not a very smart one).
I don't see what this changes.
JavaScript treats functions as objects.
I'm not sure what effect this insight will have on your programming.
What they mean, most likely, is that any data that can be assigned to a variable has properties (and therefore methods) that can be accessed in an object like fashion.
// strings
"asdf".length; // 4
"asdf".replace('f', 'zxc'); // "azxc"
// numbers
(10).toFixed(2); // "10.00"
// booleans
true.someProp; // undefined (point is it doesn't crash)
They even have prototypes they inherit from.
"omg".constructor; // function String() { [native code] }
String.prototype.snazzify = function() {
return "*!*!*" + this + "*!*!*";
};
"omg".snazzify(); // "*!*!*omg*!*!*"
However, these are primitives, and while they behave object like in a lot of ways, they are different from other "real" JS objects in a few ways. The biggest of which is that they are immutable.
var s = "qwerty";
s.foo; // undefined, but does not crash
s.foo = 'some val'; // try to add a property to the string
s.foo; // still undefined, you cannot modify a primitive
Do note though that functions are real mutable objects.
var fn = function(){};
fn.foo; // undefined
fn.foo = 'some val'; // try to add a property to the function
fn.foo; // "some val"
So while it's not technically true that "everything in JS is an object", under most circumstances you can treat them mostly like objects in that they have properties and methods, and can potentially be extended. Just be sure you understand the caveats.
NOT everything in JavaScript is an object.
All data in JavaScript must fall into one of six primitive types, or the object type. Primitive types includes boolean, null, undefined, string, number and symbol; everything that is not a primitive is an object.
This means functions are objects, arrays are objects, ES6 classes de-sugars into a function which are objects.
The confusion arises because primitive values have object wrappers. When you try to access the length property on the string literal, JavaScript creates a temporary object wrapper around the primitive and access the length property of that object wrapper. After the property has been retrieved, the object wrapper is discarded. This is known as autoboxing.
Essentially, it is implemented similar to the following:
const foo = "bar";
// When you run `foo.length`, it's similar to
tmp = String(foo);
tmp.length;
delete tmp;
Or
const foo = "bar";
(new String(foo)).length;
The string, number and boolean primitives have object wrappers, but null and undefined do not. So trying to access a property or method from those primitives would throw an error.
null.length; // Uncaught TypeError: Cannot read property 'length' of null
undefined.length; // Uncaught TypeError: Cannot read property 'length' of undefined
Not everything is an object in JavaScript. For example a number is not an object.
Different languages have different definition of "object". For JavaScript, the official definitions can be found in the ECMAScript Language Specification, which states:
In ECMAScript, an object is a collection of zero or more properties
each with attributes that determine how each property can be used (...) Properties are containers that hold other objects,
primitive values, or functions. A primitive value is a member of one
of the following built-in types: Undefined, Null, Boolean, Number,
BigInt, String, and Symbol; an object is a member of the built-in type
Object; and a function is a callable object.
So by this definition it is clear that primitive values (like numbers) are not objects. Even strings are not objects, which is different from most other OO languages.
So why do some people say "everything is an object"? You have to ask them! But I suspect it is because they are getting confused by the built-in objects Number, Boolean, String etc. which can be used as wrappers around the corresponding primitive values. This wrapping sometimes happen automatically, which can make primitive values look like object and for example allow you to (seemingly) access properties on primitives. But in reality the properties are on the wrapper object.
'ALMOST everything is an object' because the MAIN code-units are JS-objects. On primitives you can NOT add members for example as on all objects. My answer why JS-functions are JS-objects here: https://stackoverflow.com/a/24811539
Related
Are arrays merely objects in disguise? Why/why not? In what way(s) are they (such/not)?
I have always thought of arrays and objects in JS as essentially the same, primarily because accessing them is identical.
var obj = {'I': 'me'};
var arr = new Array();
arr['you'] = 'them';
console.log(obj.I);
console.log(arr.you);
console.log(obj['I']);
console.log(arr['you']);
Am I mislead/mistaken/wrong? What do I need to know about JS literals, primitives, and strings/objects/arrays/etc...?
Are arrays/objects merely strings in disguise? Why/why not? In what way(s) are they (such/not)?
Arrays are objects.
However, unlike regular objects, arrays have certain special features.
Arrays have an additional object in their prototype chain - namely Array.prototype. This object contains so-called Array methods which can be called on array instances. (List of methods is here: http://es5.github.com/#x15.4.4)
Arrays have a length property (which is live, ergo, it auto-updates) (Read here: http://es5.github.com/#x15.4.5.2)
Arrays have a special algorithm regarding defining new properties (Read here: http://es5.github.com/#x15.4.5.1). If you set a new property to an array and that property's name is a sting which can be coerced to an integer number (like '1', '2', '3', etc.) then the special algorithm applies (it is defined on p. 123 in the spec)
Other than these 3 things, arrays are just like regular objects.
Read about arrays in the spec: http://es5.github.com/#x15.4
Objects are an unordered map from string keys to values, arrays are an ordered list of values (with integer keys). That's the main difference. They're both non-primitive, as they're composed of multiple values, which also implies pass-by-reference in JavaScript.
Arrays are also a kind of object, though, so you can attach extra properties to them, access their prototype and so on.
In your revised example, you're only taking advantage of the fact that an array is actually an object, i.e. you can set any property on them. You shouldn't do that. If you don't need an ordered list of values, use a plain object.
Strings can be either primitive or objects, depending on how they were declared.
var str = 'yes';
Gives you a primitive, while,
var str = new String('yes');
will give you a String object.
All arrays are the same (Whether or not they were defined with [] or new Array()), are of the type object and inherit from the "Array" object's prototype. There aren't real classes in Javascript, everything is an object, and there's a system defined object called Array. It has a property called 'prototype' (of type object), and when you use the new keyword on an object with a prototype property, it creates an instance with a reference to the contents of the prototype and stores it in your variable. So all arrays you've ever used in Javascript are objects and instances of Array's prototype property.
In any case, although arrays really are objects, they behave like arrays because of their useful properties and functions (Such as length, slice, push etc).
Another note, although I said there are no classes, when you do this:
console.log(Object.prototype.toString.call(your_object));
it will give you a string in the form [object Object]. But what's useful is that when you call it with an array, you get [object Array] same with functions which give [object Function] and a number of other system defined types, which assists in differentiating between normal objects and arrays (Since the typeof operator will always just return the string 'object').
Try this
var a = Array;
and go into firebug and examine the contents of a, especially it's 'prototype' property.
Edit: Changed the wording a bit, to be more correct. In fact when you use the new keyword, it creates an instance which references the prototype object. So any changes made to the prototype after the instance's declaration, will still affect the instance.
Edit: In answer to your latest revised question (are arrays/objects actually strings in disguise): No. They are objects, as I've explained. Strings are either a primitive type, or an object type (An instance of the String object) which contains the primitive equivalent as one of it's properties.
Arrays are not primitives in Javascript, they are objects. The key difference is that as a result, when you pass an array to a function it is passed by reference, not by value.
So yes! Arrays are objects in javascript, with a full blown Array.prototype and everything (don't touch that though...)
The confusion comes from the fact that javascripts lets you access object attributes in two ways:
myObj.attribute
or
myObj["attribute"]
Really what makes an array an array has nothing to do with the way you store data -- any object can store values using the syntax you use to store the array -- what makes an array an array is the fact that array methods (e.g. shift() and sort()) are defined for Array.prototype.
Trying to be brief with what I believe to be of the most significance: arrays have a number of methods that objects do not. Including:
length
push
pop
An object declared as var x = {foo:bar} has no access to a .length() method. They are both objects but with the array as a sort of superset with methods mentioned as above.
I don't feel I this is even close to being of Crockford standard in terms of explanation but I'm trying to be succinct.
If you want to get some quick results, open up Firebug or your javascript Console and try Array.prototype and Object.prototype to see some details
Update: In your example you declare an array and then do:
foo['bar'] = 'unexpectedbehaviour';
will produce unexpected results and won't be available in simple loops such as:
var foo=[0,1];
foo['bar'] = 2;
for(var i=0;i<foo.length;i++){
console.log(foo[i]);
}
//outputs:
//0
//1
An array can accept foo['bar']=x or foo.bar=y like an object but won't necessarily be available to be looped through as highlighted above.
Not that I'm saying that you can't iterate through the properties of an object, just that when working with an Array, you're utilising that unique functionality and should remember not to get confused.
In JavaScript you have a few types, everything else is an object. The types in JavaScript are: boolean, number, and string. There are also two special values, "null" and "undefined".
So the quest "is a JavaScript array an object?" is slightly ambiguous. Yes, a JavaScript array is an "object" but it is not an instance of "Object". A JavaScript array is an instance of "Array". Although, all objects inherit from Object; you can view the inheritance chain on the MDC. Additionally, arrays have slightly different properties than an object. Arrays have the .length property. They also have the .slice(), .join(), etc methods.
Douglas Crockford provides a nice survey of the language's features. His survey discusses the differences you are asking about. Additionally, you can read more about the difference between literals and constructors in question #4559207.
Arrays are Objects, but of a specialized nature. Objects are collections of values indexed by keys (in Javascript notation, {'key': 'value'}), whereas Arrays are Objects whose keys are numeric (with a few functions and properties). The key difference between them is obvious when you use a for each loop--an Object will iterate over all the values in its properties, whereas an Array will return the keys instead. Here's a link to a JSFiddle demonstrating the difference--notice that the first for each, which uses an array, returns the indexes, not the values; in contrast, the second for each returns the actual values at those keys.
Are arrays merely objects in disguise? Why/why not? In what way(s) are they (such/not)?
I have always thought of arrays and objects in JS as essentially the same, primarily because accessing them is identical.
var obj = {'I': 'me'};
var arr = new Array();
arr['you'] = 'them';
console.log(obj.I);
console.log(arr.you);
console.log(obj['I']);
console.log(arr['you']);
Am I mislead/mistaken/wrong? What do I need to know about JS literals, primitives, and strings/objects/arrays/etc...?
Are arrays/objects merely strings in disguise? Why/why not? In what way(s) are they (such/not)?
Arrays are objects.
However, unlike regular objects, arrays have certain special features.
Arrays have an additional object in their prototype chain - namely Array.prototype. This object contains so-called Array methods which can be called on array instances. (List of methods is here: http://es5.github.com/#x15.4.4)
Arrays have a length property (which is live, ergo, it auto-updates) (Read here: http://es5.github.com/#x15.4.5.2)
Arrays have a special algorithm regarding defining new properties (Read here: http://es5.github.com/#x15.4.5.1). If you set a new property to an array and that property's name is a sting which can be coerced to an integer number (like '1', '2', '3', etc.) then the special algorithm applies (it is defined on p. 123 in the spec)
Other than these 3 things, arrays are just like regular objects.
Read about arrays in the spec: http://es5.github.com/#x15.4
Objects are an unordered map from string keys to values, arrays are an ordered list of values (with integer keys). That's the main difference. They're both non-primitive, as they're composed of multiple values, which also implies pass-by-reference in JavaScript.
Arrays are also a kind of object, though, so you can attach extra properties to them, access their prototype and so on.
In your revised example, you're only taking advantage of the fact that an array is actually an object, i.e. you can set any property on them. You shouldn't do that. If you don't need an ordered list of values, use a plain object.
Strings can be either primitive or objects, depending on how they were declared.
var str = 'yes';
Gives you a primitive, while,
var str = new String('yes');
will give you a String object.
All arrays are the same (Whether or not they were defined with [] or new Array()), are of the type object and inherit from the "Array" object's prototype. There aren't real classes in Javascript, everything is an object, and there's a system defined object called Array. It has a property called 'prototype' (of type object), and when you use the new keyword on an object with a prototype property, it creates an instance with a reference to the contents of the prototype and stores it in your variable. So all arrays you've ever used in Javascript are objects and instances of Array's prototype property.
In any case, although arrays really are objects, they behave like arrays because of their useful properties and functions (Such as length, slice, push etc).
Another note, although I said there are no classes, when you do this:
console.log(Object.prototype.toString.call(your_object));
it will give you a string in the form [object Object]. But what's useful is that when you call it with an array, you get [object Array] same with functions which give [object Function] and a number of other system defined types, which assists in differentiating between normal objects and arrays (Since the typeof operator will always just return the string 'object').
Try this
var a = Array;
and go into firebug and examine the contents of a, especially it's 'prototype' property.
Edit: Changed the wording a bit, to be more correct. In fact when you use the new keyword, it creates an instance which references the prototype object. So any changes made to the prototype after the instance's declaration, will still affect the instance.
Edit: In answer to your latest revised question (are arrays/objects actually strings in disguise): No. They are objects, as I've explained. Strings are either a primitive type, or an object type (An instance of the String object) which contains the primitive equivalent as one of it's properties.
Arrays are not primitives in Javascript, they are objects. The key difference is that as a result, when you pass an array to a function it is passed by reference, not by value.
So yes! Arrays are objects in javascript, with a full blown Array.prototype and everything (don't touch that though...)
The confusion comes from the fact that javascripts lets you access object attributes in two ways:
myObj.attribute
or
myObj["attribute"]
Really what makes an array an array has nothing to do with the way you store data -- any object can store values using the syntax you use to store the array -- what makes an array an array is the fact that array methods (e.g. shift() and sort()) are defined for Array.prototype.
Trying to be brief with what I believe to be of the most significance: arrays have a number of methods that objects do not. Including:
length
push
pop
An object declared as var x = {foo:bar} has no access to a .length() method. They are both objects but with the array as a sort of superset with methods mentioned as above.
I don't feel I this is even close to being of Crockford standard in terms of explanation but I'm trying to be succinct.
If you want to get some quick results, open up Firebug or your javascript Console and try Array.prototype and Object.prototype to see some details
Update: In your example you declare an array and then do:
foo['bar'] = 'unexpectedbehaviour';
will produce unexpected results and won't be available in simple loops such as:
var foo=[0,1];
foo['bar'] = 2;
for(var i=0;i<foo.length;i++){
console.log(foo[i]);
}
//outputs:
//0
//1
An array can accept foo['bar']=x or foo.bar=y like an object but won't necessarily be available to be looped through as highlighted above.
Not that I'm saying that you can't iterate through the properties of an object, just that when working with an Array, you're utilising that unique functionality and should remember not to get confused.
In JavaScript you have a few types, everything else is an object. The types in JavaScript are: boolean, number, and string. There are also two special values, "null" and "undefined".
So the quest "is a JavaScript array an object?" is slightly ambiguous. Yes, a JavaScript array is an "object" but it is not an instance of "Object". A JavaScript array is an instance of "Array". Although, all objects inherit from Object; you can view the inheritance chain on the MDC. Additionally, arrays have slightly different properties than an object. Arrays have the .length property. They also have the .slice(), .join(), etc methods.
Douglas Crockford provides a nice survey of the language's features. His survey discusses the differences you are asking about. Additionally, you can read more about the difference between literals and constructors in question #4559207.
Arrays are Objects, but of a specialized nature. Objects are collections of values indexed by keys (in Javascript notation, {'key': 'value'}), whereas Arrays are Objects whose keys are numeric (with a few functions and properties). The key difference between them is obvious when you use a for each loop--an Object will iterate over all the values in its properties, whereas an Array will return the keys instead. Here's a link to a JSFiddle demonstrating the difference--notice that the first for each, which uses an array, returns the indexes, not the values; in contrast, the second for each returns the actual values at those keys.
I'm a bit confused by the Array.length property (i.e. a property named length on the Array function object) and array_instance.length (i.e. a property named length on instance of array object)
So what is difference between the two length property and when should/shouldn't we use them?
Edit 1:
there is also a length property on Array.prototype object. I am so confused.
Edit 2
Just to paint a clearer picture, here are the different length properties I have found
Edit 3
This is one of the follow up questions I asked in the comment section, but I think the question is important to fully understanding length property, so I have copy-pasted here in the main section
Follow up question:
Array.prototype.hasOwnProperty('length') and Array_instance.hasOwnProperty('length') return true, does that mean there are two length properties, one on array_instance, one on Array.prototype object, with the array_instance.length overshadowning the Array.prototype.length?
functions have a .length property which corresponds to how many arguments they are expecting. For example:
const unary = (a) => {
}
const binary = (a, b) => {
}
console.log(unary.length);
console.log(binary.length);
So the Array constructor has a length of 1 because it expects one parameter to be passed to it (namely, the size of the array).
array objects also have a .lengthproperty, which is unrelated other than having the same name. This property says how large the array currently is.
I really think a lot of the other answers have covered everything needed here, but as it seems the OP hasn't had what they see a a clear answer, I will try to set everything out, somewhat extensively - but as clearly as I can - in order to clarify. (Apologies if anyone thinks I am "stealing" their answer - I assure you that this is not the intention, and I'm deliberately not looking at them as I type this, but I've certainly read most of them and even upvoted a few.)
Array.length
This has already been well-covered above. Array is a native JS function, which you can use for creating arrays. It's less common then simply defining an array literal (and as far as I know there is no reason it would ever be preferable), but instead of var a = [1,2,3] you are allowed to do this:
var a = Array(1,2,3);
console.log(a);
Note in passing that you don't want to do this to create a singleton array, there is an utterly mad gotcha of a special case when you supply exactly one parameter which happens to be an integer:
var a = Array(5);
console.log(a);
Although that shows what appears to be an array of 5 undefined values in whatever JS console implementation SO uses, that's not actually quite what has been created (nor what is displayed in the current version of Chrome). I'm getting way off-topic but I'll refer you to Kyle Simpson's excellent walkthrough of the madness.
Anyway, since Array is a function, as others have already observed, it has a length property as all functions do. I'm really not sure why it evaluates to 1 though - for a user-defined function it is the number of arguments the function was formally declared with, but since Array like all native JS functions isn't actually implemented in JS, I couldn't tell you how the implementation actually works. Clearly it can take any number of arguments and thus is a rather "exotic" function. I don't think that Array.length would ever be useful, no matter what value was arbitrarily assigned to it, but it seems that most implementations go for 1, even if the specification leaves it open. (I'm not enough of a spec devotee to know if this is actually defined in there or left up to implementations.)
arrayinstance.length
This is just the feature of arrays that we know and use all the time. All JS arrays get this property - note that, although it is a property rather than a method (that is, it is not a function), it nevertheless "auto-updates" as the array gets longer/shorter:
var a = [1,2,3];
console.log(a.length);
a.push(4);
console.log(a.length);
a.pop();
a.pop();
console.log(a);
console.log(a.length);
Although as I said, Javascript's native constructors are not implemented in terms of JS itself, you could implement this kind of behaviour by defining a getter (at least since ES5).
Array.prototype.length
To fully explain what Array.prototype (and similar objects) is would take me deep into how Javascript's object system work. Suffice to say here that, unlike class-based languages (and JS does not have classes, even in ES6, despite the class syntax allowing us often to pretend it does), JS does not have the usual concept of "inheritance" that so-called OO languages do. In JS's version (sometimes called "prototypal inheritance"), what happens it that each object has an "internal prototype" which references some other object - and if you try to access a property on that object which it doesn't have, the JS engine will look at that "prototype object" for the property and use its value instead.
It's actually a very simple mechanism, but there are a number of things in the language which confuse this, one of them being the fact that functions (which are also objects) have a property called prototype - which does not point to the real "prototype" object which gets consulted if a nonexistent property is referenced on the function object. (A normal function foo has Function.prototype is the object that it delegates to - not foo.prototype.) However, if you declare a function foo, an object called foo.prototype is created - which is basically an empty, nondescript object. Its significance is that if the function foo is used as a "constructor" - that is, if you make an object by calling new foo() - foo.prototype will then be the object that JS will look up properties (including methods) on if any object constructed from foo happens to fail a property lookup.
This is why, at least in pre-ES6 code, you quite frequently saw this kind of pattern:
function foo(a,b) {
this.a = a;
this.b = b;
}
foo.prototype.add = function() {
this.a = this.a + this.b;
}
var myFoo = new foo(1,2);
console.log(myFoo.a);
myFoo.add();
console.log(myFoo.a);
myFoo.add();
console.log(myFoo.a);
console.log(myFoo.hasOwnProperty("add"));
Despite appearances, myFoo doesn't actually have a method add in this example - as confirmed by the final console.log. When the JS engine fails to find the property though, it goes to myFoo's "internal prototype", which happens to be foo.prototype. And that's why the method works, as it would on any object constructed from foo.
Anyway, this is leading up to the fact that Arrays, which could be (although almost never are) constructed by calling new Array (I didn't use the new operator above, but I could have done, this is a case where it makes no difference), therefore delegate to Array.prototype. All those array methods that you know and love don't "really" exist on the arrays you call them on:
var a = [1,2,3];
a.push(4);
console.log(a);
console.log(a.hasOwnProperty("push"));
console.log(Array.prototype.hasOwnProperty("push"));
So array methods only work because those methods are actually found on the Array.prototype object, to which all arrays delegate for property/method access if the lookup doesn't succeed on the array itself. (And this is why, if you look up any of them on MDN, the top of the page always says Array.prototype.<method_name>, because that's where the method "really" lives.)
A drastic demonstration of this (please DON'T do this in production code!)
// you're used to doing this, and it works:
[1,2].push(3);
console.log("that went fine");
// vandalism on a grand scale!
Array.prototype.push = undefined;
// now you can'tse the "push" method anymore!
[1,2,3].push(4);
But I'm going to end on something of an anticlimax. The above is true for array methods - but the length array property isn't a method. As observed above, it's just a "plain" (non-function) property, which "magically" behaves somewhat like a function call. As observed in the OP, .length property accesses don't delegate as the method calls shown above do, the property exists on each array in itself.
So why does Array.prototype still itself have a length property? Well, Array.prototype is actually itself an array. In fact, that's not the only thing:
Array.prototype.push(1);
console.log(Array.prototype);
Function.prototype();
notice that Array.prototype.push(1) ends up with Array.prototype being the singleton array [1]. So Array.prototype is "kind of like" the empty array (it's not exactly the same, because it has all those methods mentioned above directly accessible on the object itself, which a "normal" empty array doesn't). And with Function.prototype, although calling it didn't output anything, the fact that no TypeError was raised proves that it really is a function (it's actually a "no-op" function, like function() {}, but once again with various methods diretcly on it - the methods which every function has access to, such as .call and .bind).
Anyway, to cut the digression short, since Array.prototype is - as far as ordinary array properties are concerned, at least - an empty array, this explains why it has a length property, and why it's equal to 0.
I hope this clears things up, as well as demonstrating some of the more intriguing parts of Javascript.
The first part has already been answered, Array constructor is a function and functions have a .length property.
For the second, Array.prototype.length, it's a bit more obscur...
Array.prototype is actually an Array:
console.log(Array.isArray(Array.prototype)); // true
Array.prototype.push('hello');
console.log(Array.prototype.length); // 1
console.log(Array.prototype[0]); // "hello"
As to why is it an Array? Because specs say so:
The Array prototype object is an Array exotic objects and has the internal methods specified for such objects. It has a length property whose initial value is 0 and whose attributes are { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }..
There is also a note specifying that it is for compatibility reasons with previous versions of the specs.
As to why is was designed as being an Array? I have no really strong idea...
Disclaimer:
I have tried to show how constructor and instance works in general. But in fact, they have huge difference between different constructors.
Any constructor has been set its length with the value specified by the spec. Specially most of them are set to 1:
Number.length // 1
Object.length // 1
Function.length // 1
Array.length // 1
// etc.
Similarly,
Array.constructor.length // 1
// etc.
Like #Kaiido pointed out in the comment, you can see some constructor length is set:
Document.length // 0
Int8Array.length // 3
Date.length // 7
And you may also notice the length of the instance is undefined as they are not set. - It's out of the scope though.
let d = new Date
d.length === undefined // true
See at the bottom for relevant references.
But when you have an instance of it, then you're creating a new value of it:
typeof new Array === typeof Array.prototype // true
typeof new Function === typeof Function.prototype // true
// etc.
So, when you use an instance it has no length value set because it has no any parameters:
let arr = new Array // Array.prototype
arr.length === 0 // true
But when you use an instance with parameter, then you have the length property with the value of parameters
let arr = new Array(20)
arr.length === 20 // true
let func = function(a1,a2,a3,a4){}
func.length === 4 // true
// etc.
So now, you have been wondering why the constructor has length value equal to 1?
It's because the spec has set the value to be 1 initially.
Every built-in Function object, including constructors, has a length property whose value is an integer. Unless otherwise specified, this value is equal to the largest number of named arguments shown in the subclause headings for the function description, including optional parameters.
The value of the [[Prototype]] internal slot of the Object constructor is the intrinsic object %FunctionPrototype%.
Besides the length property (whose value is 1),
See these references:
Standard built in objects,
19.1.2 Properties of the Object Constructor,
19.2.2 Properties of the Function Constructor,
etc.
Also, you can see the prototype has length to 0, you already know it why in the preceding example.
Though, here's just a reference stating that:
19.2.3 Properties of the Function Prototype Object
And there some constructor whose length is set different. This is the out of scope of this answer. Though, here's a reference for the date constructor:
20.3.3 Properties of the Date Constructor
So, it's totally up to the spec how they have been defined.
Array.length
Array is constructor which means its type is "function". You try the checking it console.
typeof Array //"function"
According to MDN
The length property indicates the number of parameters expected by the function.
As the Array function expects single argument so Array.length = 0
array_instance.length
The length property of an object which is an instance of type Array sets or returns the number of elements in that array
As we know that arrays are actually objects so objects can have properties. The property length is on the instance of array.
Now second question you may ask why we don't get the length properties of array using Object.keys or for..in loop. The answer is because this property is not Enumerable.
let arr= [];
//this.property 'length2' will not be shown in for..in or Object.keys();
Object.defineProperty(arr,'length2',{
value:'length2 for test',
enumerable:false
})
//this property 'x' will be displayed in for..in loop and Object.keys()
Object.defineProperty(arr,'x',{
value:'length2 for test',
enumerable:true
})
console.log(Object.keys(arr)); //["x"]
Array.prototpe.length
According to the DOCS
The initial value of Array.prototype.constructor is the standard built-in Array
The Array prototype object is itself an array; its [[Class]] is "Array", and it has a length property (whose initial value is +0) constructor
Actually Array.prototype is an array. And remember array is always object. So it can have properties. The methods of the Array are stored in form of key:value. and there is no element in that array so it Array.prototype.length returns 0. If you push() some elements into it you will see it as array.
console.log(Array.prototype.length) //0
console.log(Array.isArray(Array.prototype)) //true
//adding element to array
Array.prototype.push('x')
console.log(Array.prototype.length) //1
As I explained in second parts you can hide properties of Object by setting enumerable:false. All the methods are keys of Array.prototype But now shown in for..in loops.
Array.length
For the number of properties in the array or the length property of an object which is an instance of type Array sets or returns the number of elements in that array.
Array.prototype.length
Inherited number of properties in the array. When you check Array.length you're actually checking Array.prototype.length
I'm currently doing a bit of JavaScript and I have some troubles trying to explain myself one thing.
If I do that :
var text = new String("Enter any value here");
We all agree that "text" is an object, right?
But what should be "String" called then? Because I see everywhere that String is also an object, but wouldn't it be simpler to call it a class like in PhP.
Is there an other name, more precise than just object for String?
If someone can explain me the subtlety, I would be very happy. Thank you!
I think the source of your confusion is unfamiliarity with Prototypal Inheritance model. I suppose you are well versed with 'Classical Model' where classes are constructed using Classes as blueprint. On the other hand in JavaScript other Objects are created using an Object as a prototype or using an empty object and then pinning new properties in it.
If you try logging typeof(String) you will get output as function. Here when we do a new String('hello, world'), we get a new String object Hello, World. Thus String is a constructor in JavaScript.
By design, JavaScript (the implementation of the ECMAScript standard) has no class. So String cannot ever be called a class.
String here is but an object, just as almost everything in JavaScript is (as some the answers have already stated).
console.log(String instanceof Object); // true
Actually a special object: a function.
console.log(typeof String); // "function"
console.log(String instanceof Function); // true
And even a special function: a function that should be called as a constructor, hence the capital 'S'.
Even more special function: it is a built-in function (it is "present in the language" and therefore provided by the host environment -the browser or node, for example).
This special function allows you to instantiate an object of type String:
var aString = new String("A string");
But this is the wrong way to do it: you should write this:
var aPrimitiveString = "A string";
which interestingly, by the way, doesn't make text a String (Object), but a string (primitive).
console.log(typeof(aString)); // "object"
console.log(aString instanceof String); // true
console.log(aString instanceof Object); // true
console.log(typeof(aPrimitiveString)); // "string"
console.log(aPrimitiveString instanceof String); // false
console.log(aPrimitiveString instanceof Object); // false
Even in ECMAScript 6 (AKA ES6, AKA Harmony, AKA ES2016), there won't be any classes in the acception you have of it, "classes" in ES6 will still be an object, of type function, with prototypal inheritance.
One more thing: String can also be used to explicitly coerce a value into a string primitive:
var number = 1;
var numberAsString = String(1);
console.log(number); // 1
console.log(numberAsString); // "1"
console.log(typeof number); // "number"
console.log(typeof numberAsString); "string"
for the sake of completeness, I hope you guessed that:
number is a primitive number
numberAsString is a primitive string
new number(1) would be an object, instance of Number and Object
Number('0') would be a primitive number
same goes for Boolean
There are no classes in JavaScript, there won't ever be (I don't want any of it, anyway), that is what make the language so flexible, expressive and powerful.
Maybe you would want to take a look at this: http://javascript.crockford.com/inheritance.html (and the whole site and work of Douglas Crockford).
JavaScript is an object oriented language without classes.
However, you can apply many object oriented paradigms in JavaScript. It has its own mechanisms to do so.
In JavaScript, instead of classes you use objects. That's really about it already. You can think of String as a class if you want, but sometimes it can lead to confusion, because it is easy to confuse concepts known from Java or C++ with JavaScript. The implementation is just different.
I suggest you omit to think of it as a class, and call it an object. And try not to apply terminology of other languages like PHP with JavaScript.
Now, the confusion might be that in other OO languages you define a class and then you create instances from that class, which we refer to as objects.
In JavaScript you simply create a new copy of another object.
Please refer to this link and...
...note that JavaScript distinguishes between String objects and
primitive string values. (The same is true of Boolean and Numbers.)
According to w3schools:
In JavaScript, almost "everything" is an object.
Booleans can be objects (or primitive data treated as objects)
Numbers can be objects (or primitive data treated as objects)
Strings can be objects (or primitive data treated as objects)
Dates are always objects
Maths are always objects
Regular expressions are always objects
Arrays are always objects
Functions are always objects
Objects are objects
In JavaScript, all values, except primitive values, are objects.
Primitive values are: strings ("John Doe"), numbers (3.14), true,
false, null, and undefined.
MDN says in javascript everything are objects.
In JavaScript, almost everything is an object. All primitive types
except null and undefined are treated as objects. They can be assigned
properties (assigned properties of some types are not persistent), and
they have all characteristics of objects.
Creating new objects
JavaScript has a number of predefined objects. In addition, you can
create your own objects. You can create an object using an object
initializer. Alternatively, you can first create a constructor
function and then instantiate an object using that function and the
new operator.
So in javascript the idea of class doesn't really exist like in other languages. It's just an instantiated object or function if you prefer.
typeof 1.00 // number
typeof 1 //number
typeof "string" //string
typeof String("string") //string
typeof new String("string") //object
typeof {} //object
typeof [] //object
Demo
It seems possible to create classes in ECMAScript 6
It is said that:
Defining classes
Classes are in fact functions, and just like you can define function
expressions and function declarations, the class syntax has the two
opponents:
class expressions and class declarations.
I was reading this link JavaScript_syntax
This seems to be cyclic - that every function is an Object and every Object itself is a function. Which is the atomic one? Can someone explain in a better way?
Anything that is not a primitive type (undefined, null, number, string, boolean) is an object (or an instance) in JavaScript. That means function inherits from object.
Object instances can contain more instances which can be functions. That's what we call a "method" (since it has an automatic this variable).
Since you can't "call" every Object instance, not every object is a function.
I think this concept is often misunderstood.
A utility to visualize JS types relationship http://jstype.herokuapp.com/#/home
Javascript Data Types
Primitive types - numbers, strings, booleans, null and undefined.
All non-primitive types are object:
var foo = { };
var foo = [1, 2, 3];
var foo = function abc() { return "hello world"; };
var foo = new Number(30);
var foo = new String("Hello World");
var foo = new Boolean(true);
var foo = new RegExp(/[foo]+/);
// All 'foo` are object.
All primitive types have a corresponding Constructor Function wiz. Array, Number, String, Boolean, RegExp. As all functions are objects, they are objects too. So we can call them Constructor Function Objects.
Most of the non-primitive type has prototype property where all inherited stuff lives. Math doesn't have prototype.
All objects inherit from Object.prototype which inherits from null.
object <- Object.prototype <- null
All native functions inherit from Function.prototype which inherits from Object.prototype.
function <- Function.prototype <- Object.prototype <- null
Arrays inherit from Array.prototype which inherits from Object.prototype.
array <- Array.prototype <- Object.prototype <- null
Must read MDN: Inheritance and prototype chain
To get confused Stackoverflow: prototype in JavaScript
Stack Overflow: Function prototype explained
Every function is an object. Objects can contain functions (methods) but an object is not necessary a function.
Also Function is always a property of an object.
This mean that all functions in JavaScript is always bound to an object. If you don't specify an object to bind a function to it's bound to the window object (Also called global functions)
..fredrik
It would be better to say that in JavaScript everything can be treated as an object, that includes primitive types as well as functions types; what the JavaScript interpreter does is that it automatically promotes your primitives and functions to their object wrapper types when you interact with them.
There is also a Function object, an a number of equivalent Wrappers for the other primitives in JavaScript, that means that you can even call methods on functions instances, like:
myFunction(someArg).call(this)
That being said, not every object is in fact a function.
As others have said, functions are objects that can be passed around by reference like other javascript objects. Not all objects are functions, only those that are declared as such.
You will often see methods declared like so:
var myFunc = function(foo, bar) {
...
};
This is to reinforce the fact that the method is a function object and as such it is a property of the object where it is defined, just like any other variable you might define with var.
This is the foundation of the most important feature in javascript, closure.
Every function is an Object.
I'm not an javascript expert, but I cannot see how every Object is a function. (I can see how every object could be a function, but that's different)
Quoting from Working with Objects - MDN Docs
section Using Object Initializers last paragraph:
"In JavaScript 1.1 and earlier, you cannot use object initializers. You can create objects only using their constructor functions or using a function supplied by some other object for that purpose. See Using a Constructor Function."
meant that all objects WERE functions! Specifically, upon evaluation, instances or instantiations of functions.
Literally, ALL objects of that vintage were created syntactically with constructs like:
"newobj = new constructFunctor(arg1,arg2){this.prop1=arg1 /* etc */}(val1,val2)"
AND in the string that makes the object "newobj" there is the word "constructFunctor", the name of a function. The statement is intentionally quoted to impress the fact that it must be eval()'d to be executed. Prior to execution "newobj" is "equated to" a function because the statement MUST have one and "is" one by virtue of "constructFunctor"'s literal existence to define newobj's value upon execution. The quoting, and not, is very intentional in order to elucidate this abstraction. However, because JavaScript DOES have an eval function, this abstraction is in fact intentionally incorporated into the JavaScript language.
The legacy of this is still fundamental to JavaScript, though some syntactic short cuts have been added as "object initializers" using the shorthand notation like: "no={}". That the paragraph quoted above is still resident in the current documentation IS significant for the very reasons noted.
Furthermore, JavaScript also exemplifies the fundamental paradigms of Functional Programming. This defines everything as a function using the abstractions of Recursive Function Theory and the Lambda Calculus! For instance 0(), 1(), 2(), ... are the constant nonary functions better known as 0,1,2,3, ...
JavaScript is completely consistent with a Functional Programming Style approach rather than the common OOPS (pun intended Object Oriented Programming Style).
Just for supplementary to Aaron Digulla's answer.
In javascript not every object is a function. But Object,Array,String and many other built-in objects are functions that used with new operator to create object. I think this is what confused most people.
javascript everything is a hashtable. Ryan Dahl said this in one of his talks. thats what json is also; a hashtable definition. thats why u can access an object using array notation or object property notation. the value of the hashtable can be a function as well which is a hashtable. or rather an associative array
type Object in the console u get { [native code] } which is a hashtable
Object is an abstract data given to a class and that class is assigned to an object. Object can have properties and properties can hold values and functions.
Or simply for the sake of making it easy to understand you can say that anything that is not primitive data type (number,string, boolean, unll & undefined) can be classified as an object.
the selected answer by Aaron Digulla's is not 100% correct because it says,
Anything that is not a primitive type (undefined, null, number,
string, boolean) is an object.
but a string is an object. That is why you can do things like:
myString="Hello World";
x = myString.length;
newString = myString.toUpperCase();
link = myString.link("http://www.hello-world.com/");
And many other methods can be applied to the string object.
You could also initialize the string like:
myString = new String("Hello, World!");
But because a string is also a datatype it is much easier to initialize it by just applying a value.
Not necessarily an answer to the question ... just a clarification/correction of Aaron Digulla's answer.
The selected answer is wrong. In JavaScript everything is a function, except primitive types. Object itself is a function which is called function Object(). Use for example the following code:
<script>
alert(Object);
</script>