I'm trying to build a contructor which accepts an object and sets it to itself.
For instance:
var Somecontructor = function(object){
this = object;
}
Obviously, I cannot assign anything to "this" because it is immutable, but I'm trying to figure out a way to do this. Any ideas?
Edit: I don't know why this question deserves negative vote. All I want to do is, construct an object that creates properities using whatever that was passed as arguments. Sure, I can do this and I wanted to find the most efficient way to do it. If your answer doesn't work, please don't be a terrible human being by negative voting the question.
This will copy all of the properties of one object to the properties of a new object.
var SomeConstructor = function(obj) {
for(key in obj) {
this[key] = obj[key];
}
}
You seem to be wanting to clone an object. For that, you need not use a constructor function.
var cloneObj = function(obj){
return JSON.parse(JSON.stringify(obj));
}
console.log(cloneObj({
property1: "One",
property2: "Two",
}));
Related
I've been playing with and studying the prototype chain in Javascript and this subject got me wondering... is there a common name or term to refer to the object that everything else in the end of the prototype chain?
I'm writing a markdown file on a GitHub repo of mine and there I refer to it as the "God" object. But I'm quite unsure about how this object behaves.
Could I, for example, change the reference on one specific type of Object (lets say, Dog object) to have its own "God", or will I be stuck with this one single "God" object?
The "God" object you're referring to is Object.prototype.
console.log({}.__proto__ === Object.prototype);
console.log({}.__proto__.__proto__);
If you want to create your own "God" object, use Object.create(null)
var obj = Object.create(null);
console.log(obj.__proto__);
It is commonly used when creating a lookup table, so as to avoid any name conflicts with fields in the prototype, such as toString.
function Map() {
var table = Object.create(null);
return {
put: function(key, val) {
table[key] = val;
},
get: function(key) {
return table[key];
}
};
}
var map = new Map();
console.log(map.get('toString'));
map.put('toString', 'test');
console.log(map.get('toString'));
So I have a JavaScript function that gets an object and has a precreated object. The goal is that the function adds all missing properties of the passed object to the precreated one.
When just comparing one level, this is easy. For example in order to achieve this:
Precreated: {hello: "world"}
Passed: {hello: "there", colour: "green"}
Result: {hello: "world", colour: "green"}
You just look over each key of the passed object, look if that key already exists in the precreated one, and if not, add it with the respective value.
However, if you want to do this with multiple levels it kinda gets weird. For example, I want this to work:
Precreated: {hello: {there: true}}
Passed: {hello: {world: true}}
Result: {hello: {there: true, world: true}}
My idea was that I would just loop over the passed object, and if I find an object inside, call the function again with that object, and so on until all children were processed by the function.
When you do that, however, you would have to compare the children of both objects dynamically. Say, I know in the programme how many levels deep it is, what the key is called and so on, how do I programmatically access it?
I'm asking because I can't hardcode something like if (result[key1][key2][key3]..., and something like if (result[keys.join(..)]... isn't possible as well I think.
So how do I programmatically access a property of an object which is multiple levels deep, not knowing how deep at the time of writing the code?
This existing answer to a post mentioned by #4castle should be exactly what you want: https://stackoverflow.com/a/34749873/1406083
My idea was that I would just loop over the passed object, and if I find an object inside, call the function again with that object, and so on until all children were processed by the function.
You've already worked out that you want to use recursion, which is great. JavaScript allows you to reflect on the keys of an object with a for ... in loop. You just need to make sure that the object you want to copy is indeed an object and not just a value.
The answer I linked uses their own isObject for this. Object filling is done recursively with Object.assign
You can use for..of loop, Object.keys() to check if property of passed object is an object, if true recursively call function with original object, passed object and key of passed object as parameters then assign property to original object, else check if property does not exist in original object, if true assign passed property to original object.
var precreated1 = {
hello: {
there: true
}
};
var precreated2 = {
hello: "world"
};
function addProps(props, obj, key) {
for (let prop of Object.keys(props)) {
if (Object.getPrototypeOf(props[prop]) === Object.prototype) {
addProps(props[prop], obj, prop)
} else {
if (key) {
obj[key][prop] = props[prop]
} else {
if (!(prop in obj)) {
obj[prop] = props[prop]
}
}
}
}
}
addProps({
hello: {
world: true
}
}, precreated1);
console.log("precreated1:", precreated1);
addProps({
hello: "there",
colour: "green"
}, precreated2);
console.log("precreated2:", precreated2);
I am trying to get the first object within an object.
I have something like
var object = {
task:{
config:'auto',
title :'test'
},
prop:'switch',
time:'5min'
}
My problem is task object could be named differently. so it could be
var object = {
task2:{
config:'manual',
title :'test2'
},
prop:'switch',
time:'5min'
}
I can't use object.task1.config because task name could changed. The task object will always be the first object though.
I want to get the task object no matter what name it has. How do I accomplish that? Thanks!
To get the first property value of an object in modern browsers you could use the Object.keys method:
var myObject = {
whoTheHellKnows: 'foo',
notUsed: 'whatever'
};
var firstProperty = myObject[Object.keys(myObject)[0]];
Working example
Edit: if you do not trust the ordering of the properties (which you should not) AND the task object is the only nested object in your objects, you can rely on type interrogation to find it:
var myObject = {
task123215452: { dahKey: 'foo' },
notUsed: 'whatever',
somethingElse: 42
};
var taskObject;
for (var key in myObject) {
if (typeof myObject[key] === 'object' && !(myObject[key] instanceof Array)) {
taskObject = myObject[key];
break;
}
}
Working example
If you need to access the first key and you don't know the key name, you should really be using an array instead of an object. Objects don't have the concept of a "first" key.
If that's not an option, you're left with for..in or Object.keys, which may fail on some JavaScript implementations because the language specification does not enforce the order of object key enumerations. However, in practice, it will work on current browsers, as they all iterate the keys in the order they were declaredcitation needed thanks to jbabey.
I've been using dean edwards base.js (http://dean.edwards.name/weblog/2006/03/base/) to organise my program into objects ( base.js is amazing btw, if you havent used it before !).Anyway, my question is generic and you don't have to know base.js to know my answer.
I have a property in one of my objects called ref which is a reference to a DOM element, and this object is meant to be saved as JSON using JSON.stringify, but as you can imagine since DOM elements are circular structure, I won't be able to convert the object into JSON.
Now to get around this problem I have a method called html() which is meant to return the ref property, but I need to have ref as a private property which is only accessible from within the object, and hence won't be sent to stringify.
What's the best way to do that?
You probably know that you cannot have private properties in JavaScript.
Interestingly, if you pass an object to JSON.stringify which has a method toJSON, JSON.stringify will automatically call that method to get a JSONable representation of that object. So all you have to do is implement this method.
For example you can create a shallow copy of the object which only contains the properties you want to copy:
MyConstructor.prototype.toJSON = function() {
var copy = {},
exclude = {ref: 1};
for (var prop in this) {
if (!exclude[prop]) {
copy[prop] = this[prop];
}
}
return copy;
};
DEMO
Another way would be to use a custom replacer function, but it might be more difficult to control which ref to exclude and which one to keep (if different objects have ref properties):
JSON.stringify(someInstance, function(key, value) {
if(key !== 'ref') {
return value;
}
});
DEMO
here is sample to to set variable visibility
function Obj(){
this.ref = 'public property'; // this property is public from within the object
var ref = 'private proerty'; // this property is private.
var self = this;
this.showRef = function(){
alert(ref);
alert(self.ref);
};
}
var obj = new Obj();
obj.showRef();
I have a simple object (or hash) in Javascript:
var settings = {
link: 'http://example.com',
photo: 'http://photos.com/me.jpg'
};
I need a copy of it. Is there a settings.clone() type method that will give me another object with the same attributes? I'm using jQuery, so happy to use a jQuery utility method if one exists.
Yes, extend an empty object with the original one; that way, everything will simply be copied:
var clone = $.extend({}, settings);
Extending some filled object with another, e.g.:
$.extend({a:1}, {b:2})
will return:
{a:1, b:2}
With the same logic:
$.extend({}, {foo:'bar', test:123})
will return:
{foo:'bar', test:123}
i.e. effectively a clone.
In a non jQuery way.
var newObj = {};
Object.keys(settings).forEach(function(key) {
newObj[ key ] = settings[ key ];
});
This copies only the top-level properties. To copy hashes with nested objects as property values, you will need to use a recursive function.
NB: The Object.keys(settings) avoids the need for calling settings.hasOwnProperty(key).
var clone = $.extend(true, {}, settings);
Set first argument to true.
EDIT: First argument true signifies deep copy. For given example in original question there is no need for deep copy since there are simple immutable key-value pairs. For question in title - as a general case - use deep copy. Otherwise you get half-copy.
It sounds like you want jQuery extend, which can copy an object for you.
http://api.jquery.com/jQuery.extend/
My 2 cents:
function clone(hash) {
var json = JSON.stringify(hash);
var object = JSON.parse(json);
return object;
}
It may not be the most optimized option but it can be handy for some scenarios.
Underscore.js also has an extend function if you are not using jQuery:
extend _.extend(destination, *sources) Copy all of the properties in the source objects over to the destination object, and
return the destination object. It's in-order, so the last source will
override properties of the same name in previous arguments.
_.extend({name: 'moe'}, {age: 50});
=> {name: 'moe', age: 50}