OK, I really have read everything I can find trying to get a comprehensive understanding of Javascript. I know this can be done using a constructor function, but I'm trying to understand the language enough to know why this happens...
PeepClass = { color: "Yellow", shape: "Chick" };
var peepsA = new Object(PeepClass);
var peepsB = new Object(PeepClass);
if ( peepsA == peepsB )
document.write( "Why wouldn't these be unique instances?" );
Why doesn't new Object(PeepClass) create unique instances of the PeepClass object? Instead, it results in three references to the same object.
I guess you want this:
var peepsA = Object.create( PeepClass );
Now peepsA is a new object which inherits from the object PeepClass.
Btw when you pass an object into new Object(), that same object is returned, ergo, the operation is a no-op.
PeepClass === new Object( PeepClass )
which means that the notation new Object( obj ) is meaningless.
To put it another way, you can initialize an object in two ways:
// these are equivalent
var o1 = new Object();
var o2 = {};
To quote MDN:
The Object constructor creates an object wrapper for the given value.
If the value is null or undefined, it will create and return an empty
object, otherwise, it will return an object of a type that corresponds
to the given value.
In other words, when you call new Object(PeepClass) what you get back is not an instance of PeepClass, but PeepClass itself.
Read about new Object([value]) construction in ECMAScript standart. If value is ECMAScript object then it doesn't create a new object, it just return the value.
Related
I have the following code:
var obj2 = new Object();
console.log(Object.isExtensible(obj2)); //returns 'true'
console.log(obj2.constructor.isExtensible()); //returns 'false'
Could anyone explain why the first console print returns boolean 'true' and the second one 'false' and what difference it makes if isExtensible() is called either way.
The .constructor of an instance refers to the class / function that instantiates an instance. Since you're doing
var obj2 = new Object();
this means that obj2.constructor is the same as Object.
So
obj2.constructor.isExtensible()
is calling Object.isExtensible, but without an argument. isExtensible requires an argument. If you pass it the obj2, it'll do what you expect:
var obj2 = new Object();
console.log(Object.isExtensible(obj2)); //returns 'true'
console.log(obj2.constructor.isExtensible(obj2));
console.log(obj2.constructor === Object);
But that's still confusing. I'd recommend never using obj2.constructor - just use Object instead, it'll make more sense.
Usually, you'd probably only want to use the .constructor property when you don't already have a reference to the class - otherwise, it's easier to just reference the class.
I'm having a strange situation in JavaScript where I am creating an Object and then passing it as an Argument to a Function which then updates the values and then returns a new updated Object.
function objBuild() {
var obj_old = {}; // original object
var obj_new = {}; // updated object
// set values for original object
obj_old.val01 = "val01_old";
obj_old.val02 = "val02_old";
obj_old.val03 = "val03_old";
// set values for new object using
// the original object as a template
obj_new = objUpdate(obj_old);
console.log(obj_old); // this shows obj_new data which I don't want
console.log(obj_new); // this shows obj_new data which I want
}
function objUpdate(obj) {
obj.val03 = "val03_new";
return obj;
}
I was expecting the new Object to be updated with the new Value, which it is, however the old Object is updated as well.
Maybe the function is taking the old Object as a reference and even though I'm returning a separate value it remembers what's happened to it?
I'm not sure but if that is the case is it possible to keep the old Object intact?
Please read: Is JavaScript a pass-by-reference or pass-by-value language?
In javascript, objects are "technically" passed by "reference". Hence, the original value is altered, because obj is, in fact, the original object.
You need to clone the object, and there is a vast scenario about "how" you should do that, since object may be shallow copied or deep copied. Read more about that here: What is the most efficient way to deep clone an object in JavaScript?
and here: How do I correctly clone a JavaScript object?
Anyway, to fix your issue, just use Object.assign on a brand new object to copy the values of the original object, for your case, it's just enough, despite I recommend you to read the above posts to learn when and how to properly copy objects.
function objBuild() {
var obj_old = {}; // original object
var obj_new = {}; // updated object
// set values for original object
obj_old.val01 = "val01_old";
obj_old.val02 = "val02_old";
obj_old.val03 = "val03_old";
// set values for new object using
// the original object as a template
obj_new = objUpdate(obj_old);
console.log(obj_old); // this shows obj_new data which I don't want
console.log(obj_new); // this shows obj_new data which I want
}
function objUpdate(obj) {
var _cloned = Object.assign({}, obj);
_cloned.val03 = "val03_new";
return _cloned;
}
objBuild();
You're not actually creating a new object, you're setting the old object to the new object. So you're correct, the old object value is still being referenced.
If you want to make a new object, and you don't have any nested objects, I would use Object.assign(). This makes a shallow copy of the object. You could do something like this:
obj_new = objUpdate(Object.assign({}, obj_old));
This will create a new object with the enumerable properties of the old object.
If you have nested objects, these will still be copied by reference, so I would loop over the object and copy the properties that way.
Remember that objects, including arrays are passed by reference while strings, booleans and numbers are passed by value.
Here, you are passing object(by reference) so it is modifying the values of old object. Both old and new objects are pointing to the same value.
function objBuild() {
var obj_old = {}; // original object
var obj_new = {}; // updated object
// set values for original object
obj_old.val01 = "val01_old";
obj_old.val02 = "val02_old";
obj_old.val03 = "val03_old";
// set values for new object using
// the original object as a template
obj_new = objUpdate(obj_old);
console.log(obj_old); // this shows obj_new data which I don't want
console.log(obj_new); // this shows obj_new data which I want
}
function objUpdate(obj_old) {
var obj = JSON.parse(JSON.stringify(obj_old));
obj.val03 = "val03_new";
return obj;
}
objBuild();
I was trying the below commands on Chrome console. I am able to create the object using new(line 2 below) but using call doesn't work. Can anyone explain what could be the reason ?
function ObjConstructor(){ this.sample = 1};
let withNew = new ObjConstructor();
let usingCall = ObjConstructor.call({});
usingCall
undefined //output that came on console, this is not a command
withNew
ObjConstructor {sample: 1} //output that came on console
new does several things including:
Creating an object
Setting the this value to that object
Causes the function to return that object by default
Your code:
Creates an object manually with {}
Sets the this value to that object with call()
… but doesn't do the last thing. There is no return statement in the function, so it returns undefined.
The result of call is whatever the function returns. Your ObjConstructor doesn't return anything, so the result of calling it is undefined.
In contrast, when you use new, a new object is created and passed to the function, and unless the function returns a non-null object, the object created for new is the result of the new expression.
That's why the new version works but the call doesn't.
Also note that call doesn't create an object at all. In your ObjConstructor.call({}), what creates the object is {}, not call. It won't have ObjConstructor.prototype as its prototype. ({} is a raw object initializer, so the object will have Object.prototype as its prototype.)
try this.
Or look at this -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects
var MyType = function(_param1,_param2){
this.param1 = _param1;
this.param2 = _param2;
this.ShowParam = function(){
alert(this.param1+" - "+this.param2);
}
}
var test = new MyType("PARAM TEST 1","PARAM TEST 2");
alert(test.param1+" - "+test.param2);
var test2 = new MyType("PARAM TEST 1.2","PARAM TEST 2.2");
alert(test2.param1+" - "+test2.param2);
test.ShowParam();
test2.ShowParam();
Couldn’t understand the difference between object and plain object in JavaScript.
I know how Object looks like but don’t understand plain object. I googled about this but couldn’t understand.
As per my understanding normal object looks like below
const object = {};
Or we do call functions as objects in JavaScript
function test() {
}
But what is plain object? how it differs with normal object. Thank you
Edit:
My confusion started about plain object after looking at below error. So my query is to understand the concept of plain object in JavaScript
Actions must be plain objects. Use custom middleware for async actions.
I think you wanted to mean Plain Old JavaScript Object as plain object.
In vanilla JavaScript a POJO (Plain Old JavaScript Object) is the simplest kind of object you could possibly have: a set of key-value pairs, created by the {} object literal notation or constructed with new Object().
Plain Old JavaScript Object:
Using the bracket's syntactic sugar also known as object literal:
var obj = {};
Using the Object() constructor:
var obj = new Object();
Other Than Plain Object:
Using a function constructor:
var Obj = function(name) {
this.name = name;
}
var c = new Obj("hello");
Using ES6 class syntax:
class myObject {
constructor(name) {
this.name = name;
}
}
var e = new myObject("hello");
Plain object(POJO - Plain Old Javascript Object)
var plainObj1 = {}; // typeof plainObj1 --> Object
var plainObj2 = {name : "myName"}; // typeof plainObj2 --> Object
var plainObj3 = new Object(); // typeof plainObj3 --> Object
Non Plain object
var Person = function(){}; //class
var nonPlainObj = new Person(); // typeof nonPlainObj --> function
An Object created by literal notation or new Object are know as plain object. example :
let a = {aaa : 1}
let b = new Object()
while Object created using function are not plain object
let C = function(){}
let d = new C()
You are talking about object literals, which is a literal object, {}. Like array literals use [] instead of new Array(). This is an object whose prototype is Object. A string is an Object too, but its prototype chain looks like: String -> Object. Arrays are Array -> Object. These are all objects.
An object literal's prototype is just, well, Object.
Any object created with object literals notation is called plain Objects in JavaScript
function Animal(){
//Some codes
}
var obj = new Animal();
In your question, you cite that you think both an object literal and a function are both "objects". In JS, function is a type, and so is object. So your original question, those two items are not objects ...
plain objects (sets of key/value pairs wrapped in { } ) are great for storing simple data sets.
var lunch={
sandwich:'furkey',
drink:'soda',
chips:true
}
like in react redux actions are written in key/value pairs.
hope you understand it.
This is how I do it now. It feels like a hazzle...
var broken_posts = new Object();
broken_posts.empty = new Array();
broken_posts.one = new Array();
var broken_posts = { empty: [], one: [] };
var broken_posts = {
empty: [],
one: []
};
The answers by Andru and Thilo are both correct, but perhaps some information on why is in order:
Avoid direct calls to the Array constructor: it's confusing and misleading. var a = new Array(5); returns [undefined,undefined,undefined,undefined,undefined], whereas var b = new Array('5'); returns ['5']. Or even var c = new Array(5,5); => [5,5].
Same applies for the direct object constructor. There's really no reason to create an object calling the basic object constructor. The only times you should use the keyword new is when creating a date object, or calling a self-made constructor function (and even in that case, there's no real need for the new keyword, there are alternative design patterns). Using the object literal {} is more common, allows for direct assignment of properties (and even methods). Besides, It's so much easier to create your objects in a JIT sort of way. Not only does it require less lines of code, with correct use of closures, or just for the one call, an object can get GC'ed once you're finished with it.
function iWantAnObject(obj)
{
if (obj instanceof Object)
{
return true;
}
return false;
}//function returns, obj is GC'ed
iWantAnObject({just:'some',rand:'Object',withA:function(){console.log('a method';}});
As opposed to this scenario:
var tempObj = new Object();
tempObj.just = 'some';//etc...
//etc...
iWantAnObjct(tempObj);
//tempObj isn't yet GC'ed
In the last example chances are: you accidentally create global variables, have various objects in memory that are no longer required, and, last but not least: isn't very in tune with the prototypal nature of JS.
I would prefer to use CoffeeScript instead.
Then you can do it this way:
broken_posts =
empty: []
one: []