Link to home
Start Free TrialLog in
Avatar of rgb192
rgb192Flag for United States of America

asked on

Redefining Objects/object properties in JS?

var clone = function (donor) {   
  if (Object.create !== undefined) {   
    clone = function (donor) {   
      return Object.create(donor);   
    };   
  } else {   
    clone = function (donor) {   
      var Proxy = function () {};   
      Proxy.prototype = donor;   
      return new Proxy();   
    };   
  }   
  return clone(donor);   
};   
var banana = {   
  heavyCream: [1, "cup", "Organic Valley"],   
  halfHalf: [1, "cup", "Organic Valley"],   
  sugar: [9/16, "cup"],   
  yolks: [3],   
  banana: [1 + 1/2, "cup, puréed"],   
  coconutMilk: [1/4, "cup"],   
  lemon: [2, "tsp", "freshly juiced Meyer lemon"],   
  vanilla: [1, "bean", "Madagascar Bourbon"]   
};   
var chunkyMonkey = clone(banana);   
chunkyMonkey.walnuts = [3/4, "cup, coarsely chopped"];   
chunkyMonkey.bittersweet = [1, "cup, coarsely grated", "Callebaut"];   
console.dir(banana);   
console.dir(chunkyMonkey);

Open in new window


Could someone walk me through what this code does? Is this code block considered "Lazy Loading?"  I believe the code redefines the clone() function and then uses clone() to copy the Banana Object (and it's properties) into a new ice cream flavor called 'chunkyMonkey'.  I understand the end result, but don't understand the functions themselves.

Isn't Object.create() a native function? If so, why is it Undefined?
What is the .prototype property for Proxy doing? Why is Proxy.prototype being passed into the clone function?
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Lets look at this one step at a time
Firstly - the .create function is standard but it is not supported in older browsers IE < 9 therefore a polyfill has been created to provided the function in case it does not exist (you can read more about this here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create)

Lazy loading - not sure what the association is with lazy loading - this has nothing to do with that. What this example demonstrates is how to clone an object - providing a polyfill for the create function if it does not exist.

Consider this code
var x = {
   name: 'Bruce Wane'
}
var y = x;
y.name = 'Batman';
console.log(x);
console.log(y);

Open in new window


Result
Batman
Batman

Open in new window


The reason this happens is because objects are assigned by reference not by value. If you want to create a copy of an object you need to clone it.
There are several strategies used for cloning - in this example they are using the create function to create an empty object and then to populate it with the properties from donor. This results in a new instance of the object being created with a duplicate of the data from the original. Now when properties are changed in the clone they don't affect the original.

Consider this code
<script>
var x = {
   name: 'Bruce Wane'
}
var y = x;
y.name = 'Batman';
console.log(x);
console.log(y);

// For new browsers where we
// now Object.create exists
var y = Object.create(x);
y.name = 'Bruce Wayne';
console.log(x);
console.log(y);
</script>

Open in new window

A simplified version of the original designed for new browsers. Output is now
Batman
Batman
Batman
Bruce Wane

Open in new window

Because we made a copy of the original object and populated it with that object's data it is now a separate entity and can be changed independently of the original
Addendum - the code presented is not a valid way of cloning an object and its properties
Consider this sample
<script>
var x = {
   id: 1,
   name: 'Bruce Wane'
}
var y = x;
y.name = 'Batman';
console.log(x);
console.log(y);

// For new browsers where we
// now Object.create exists
var y = Object.create(x);
y.name = 'Bruce Wayne';
console.log(x);
console.log(y);
</script>

Open in new window

Output is
Object { id: 1, name: "Batman" }
Object { id: 1, name: "Batman" }
Object { id: 1, name: "Batman" }
Object { name: "Bruce Wayne" }

Open in new window

Note the id property was not copied.
To properly clone an object you would need a function that does a deep copy of the properties from one object to another. A quick and dirty way of doing this is
var y = JSON.parse(JSON.stringify(x));

Open in new window

Avatar of rgb192

ASKER

// For new browsers where we
// now Object.create exists
var y = Object.create(x);

Open in new window



is this a way of creating an object

console.log(x);
console.log(y);

Open in new window


which is x and which is y

Object { id: 1, name: "Batman" }
Object { id: 1, name: "Batman" }
Object { id: 1, name: "Batman" }
Object { name: "Bruce Wayne" }

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of rgb192

ASKER

thanks
You are welcome