One place for hosting & domains

      Objects

      A Javascript Objects Tutorial


      Objects play a fundamental role in JavaScript and appear just about everywhere throughout the language. This tutorial explains what JavaScript objects are and discusses object properties, methods, and prototypes. Each topic includes examples to illustrate their concepts.

      Before You Begin

      This guide’s JavaScript examples were originally run in the Node.js interpreter. You can use our
      How to Install and Use the Node Version Manager NVM
      guide to install Node.js on your computer.

      Alternatively, you can use your web browser’s JavaScript console to run this guide’s example JavaScript code.

      • If you are using Chrome, refer to Google’s
        Run JavaScript in the Console
        documentation to learn how to access their developer tools..

      • If you are using Firefox, refer to Mozilla’s
        Browser Console
        documentation to learn how to access their developer tools..

      What Are JavaScript Objects?

      The object is the fundamental data type in JavaScript, outside of primitive data types like numbers, strings, booleans, etc.

      An object is a collection of properties. A property is a key-value pair. In JavaScript, nearly anything can be a property. This includes not just primitive data types, but also functions and other objects.

      The next couple of sections further explain JavaScript objects, properties, and methods. They also provide examples on how to use JavaScript objects.

      JavaScript Object Properties

      Objects consist of zero or more properties. These can be either primitive data types (boolean, number, string, etc.), methods (that is, functions operating within an object), or other objects.

      Each property has a key, which can be an identifier, a number, or a string. Most of the time, identifiers are used, like in the example below of a house object:

      const house = {
          address: "123 Street Rd",
          bedrooms: 2,
          baths: 1.5,
          vacant: true,
          phoneNumber: "123-456-7890",
          inquire:  function() {
              console.log("Calling " + this.phoneNumber + "....");
          }
      };
      

      Typically, you access properties using dot notation. The example accesses the value of the address property:

      house.address;
      
      '123 Street St'

      You can also use bracket notation, as shown in the example below. Sometimes, bracket notation is required, like when a property’s key is a number or when you want to reference a key using a variable:

      let currentKeyOfInterest="vacant";
      house[currentKeyOfInterest];
      
      true

      If you want to list all of the properties of an object, you can use the Object.keys method:

      Object.keys(house);
      
      [ 'address', 'bedrooms', 'baths', 'vacant', 'phoneNumber', 'inquire' ]

      The fact that the method returns an array makes it useful if you want to iterate through an object’s properties. The example JavaScript for loop iterates over the keys of the house object created at the beginning of this section:

      for (const key of Object.keys(house)) {
          if (typeof house[key] != 'function') {
              console.log("==\t" + key.padEnd(16) + "\t=>\t\t" + String(house[key]).padEnd(16) + "\t==\t");
          }
      }
      
      ==  address             =>      123 Street St       ==
      ==  bedrooms            =>      2                   ==
      ==  baths               =>      1.5                 ==
      ==  vacant              =>      true                ==
      ==  phoneNumber         =>      123-456-7890        ==

      JavaScript Object Methods

      Any property that defines a function is called a method. These properties allow objects to take an action. For example, the inquire() method on the house object above prints a message to your JavaScript console. The example below calls the inquire() method:

      house.inquire();
      
      Calling 123-456-7890....

      Methods have direct access to an object’s other properties, making them especially useful for processing information on an object. You can see this in the inquire() method itself. It takes the phoneNumber property from its parent object and processes it into a message for the user.

      JavaScript Object Self Reference

      JavaScript’s this keyword gives objects a way to reference their own properties. You may have noticed its use in the inquire() method. The method is able to reference this.phoneNumber to work with the property’s assigned value.

      Below is another example. This example uses dot notation to extend the existing house object with a new method. That method then uses the this keyword to reference two properties on its parent object:

      house.bathToBedroomRatio = function() {
          return this.baths / this.bedrooms;
      }
      
      house.bathToBedroomRatio();
      
      0.75

      How to Create a JavaScript Object

      JavaScript offers you a few different ways to create objects. Each one has its own characteristics, so which one you use depends on your needs. The next sections walk you through each approach and explain their advantages with examples.

      Using an Initializer

      Object initializers provide the most direct approach for creating an object. You can see it used to declare the house example in the
      JavaScript Object Properties
      section. With this approach, you declare your object as a variable using object literal notation.

      It has the advantage of being straightforward and is useful when declaring a standalone object that does not need inheritance.

      Below is another example of the object initializer approach:

      const socrates = {
          name: "Socrates",
          role: "Philosopher",
          fingers: 10,
          mortal: true
      };
      

      Using the Object.create() Method

      The Object.create() method allows you to create new objects from an existing object, which becomes the new object’s prototype.

      This method is useful when you want multiple objects using the same base and when you want to declare objects programmatically.

      The example below creates a base Person object, then uses Object.create() method to make a specific object as an instance of that base. You then only have to define the properties that differ from the new object — name and role in this case.

      const Person = {
          name: "Nemo",
          role: "None",
          fingers: 10,
          mortal: true
      };
      
      const socrates = Object.create(Person)
      socrates.name = "Socrates"
      socrates.role = "Philosopher"
      
      socrates.name;
      socrates.role;
      
      'Socrates'
      'Philosopher'

      Using a Constructor

      An Object constructor is a function that defines an object type. You can then create a new object of that type using the new keyword.

      This approach gives objects a consistent underlying type, and it can create iterations of relatively complex objects with a single line of code.

      Like the Object.create() method, this approach is useful when you expect to have multiple objects from the same base or want to create objects programmatically. Using a constructor function lets you use more complex operations when initializing an object.

      The example below defines the type Person through an object constructor function. With the new keyword, the example then declares two new objects using the constructor. Despite the objects having five properties, the constructor only requires two arguments (the third is optional):

      function Person(name, role, fingers) {
          this.name = name;
          this.role = role;
          this.fingers = fingers > 0 ? fingers : 10;
          this.mortal = true;
          this.greeting = function() {
              console.log("Hello, I'm " + this.name + ". I'm a " + this.role + ", and have " + this.fingers + " fingers.");
              if (this.mortal) {
                  console.log("And, as you would expect, I'm mortal.");
              } else {
                  console.log("And, as impossible as it seems, I'm immortal.");
              }
          }
      }
      
      const socrates = new Person("Socrates", "Philosopher");
      const galileo = new Person("Galileo", "Astronomer", 7);
      
      socrates.greeting();
      galileo.greeting();
      
      Hello, I'm Socrates. I'm a Philosopher, and have 10 fingers.
      And, as you would expect, I'm mortal.
      
      Hello, I'm Galileo. I'm a Astronomer, and have 7 fingers.
      And, as you would expect, I'm mortal.

      You can even extend your constructors using additional constructors. Below, a Philosopher constructor extends the Person constructor defined above:

      function Philosopher(name, fingers, branch) {
          Person.call(this, name, "Philosopher", fingers);
          this.branch = branch;
          this.greeting = function() {
              console.log("Hello, my name is " + this.name + ", and I'm a " + this.branch + " " + this.role + ".");
          }
      }
      
      const seneca = new Philosopher("Seneca", 10, "Stoic");
      
      another_socrates.greeting();
      
      Hello, my name is Seneca, and I'm a Stoic Philosopher.

      How Does JavaScript Object Inheritance Work?

      JavaScript objects are able to inherit both types and properties from parent objects. You can see this with both the Object.create() and the object constructor examples above. This is due to JavaScript’s prototype system which is discussed in the next section.

      JavaScript Object Prototypes

      Every JavaScript object holds a reference to at least one other object, called its prototype. Even the most basic object has Object as its prototype, but other objects can inherit prototypes from parent objects or from constructor functions.

      Below are two examples showing how an object can be given a prototype, one using Object.create() and the other using an object constructor. Each example uses the following Animal object for the prototype:

      const Animal = {
          name: "",
          kingdom: "Animalia",
          phylum: "Chordata",
          class: "Mammalia",
          family: "",
          genus: "",
          species: ""
      };
      
      • Objects created using the Object.create() method automatically have the parent object as a prototype. You can see from the output below that only the three properties reassigned for the indus_dolphin object show up on that object instance. All of the other properties are stored on the prototype, Animal:

          const indus_dolphin = Object.create(Animal);
          indus_dolphin.name = "Indus River Dolphin";
          indus_dolphin.family = "Platanistidae";
          indus_dolphin.genus = "Platanista";
          indus_dolphin.species = "Platanista minor";
        
          Object.keys(indus_dolphin);
          Object.getPrototypeOf(indus_dolphin);
        
        [ 'name', 'family', 'genus', 'species' ]
        {
          name: '',
          kingdom: 'Animalia',
          phylum: 'Chordata',
          class: 'Mammalia',
          family: '',
          genus: '',
          species: ''
        }
      • Objects created using object constructors receive values from the constructor’s prototype property. In this example, the constructor assigns the provided values. Then, a prototype is given for the constructor, which provides the resulting object, ganges_dolphin, with a prototype object:

          function Platanista(species_name, species) {
              this.name = species_name;
              this.species = species;
          }
        
          Platanista.prototype = Animal;
          Platanista.prototype.family = "Platanistidae";
          Platanista.prototype.genus = "Platanista";
        
          const ganges_dolphin = new Platanista("Ganges River Dolphin", "Platanista gangetica");
        
          Object.keys(ganges_dolphin);
          Object.getPrototypeOf(ganges_dolphin);
        
        [ 'name', 'species' ]
        {
          name: '',
          kingdom: 'Animalia',
          phylum: 'Chordata',
          class: 'Mammalia',
          family: 'Platanistidae',
          genus: 'Platanista',
          species: ''
        }

      Each object holds a reference to its parent prototype. This ends up creating what is called a prototype chain, connecting back from one prototype to the next. This continues until the Object prototype is reached. (Object itself actually has null as a prototype, which technically is what ends the prototype chain.)

      So, for the indus_dolphin object above, the prototype chain would be: indus_dolphin -> Animal -> Object.

      Objects can access properties from their prototype chains. When you try to access a property on an object, JavaScript starts by looking on the object itself. If it does not find the property there, JavaScript moves backward through each prototype in the chain. It keeps doing this until it either finds a prototype with the property or reaches the end of the chain.

      For example, the first of the commands below fetches the name property off of the ganges_dolphin object directly. But the second command needs to look on the prototype object to find the kingdom property. Finally, the valueOf method actually belongs to the Object prototype:

      ganges_dolphin.name
      ganges_dolphin.kingdom
      ganges_dolphin.valueOf()
      
      'Ganges River Dolphin'
      'Animalia'
      { name: 'Ganges River Dolphin', species: 'Platanista gangetica' }

      Conclusion

      JavaScript objects underpin much of the power available in the language. Objects give you access to their properties and methods. You can extend Objects after creating them and also create new Objects based off of existing ones. This guide provided an introduction to the main concepts behind JavaScript objects, including constructors, the this keyword, object inheritance.

      More Information

      You may wish to consult the following resources for additional information
      on this topic. While these are provided in the hope that they will be
      useful, please note that we cannot vouch for the accuracy or timeliness of
      externally hosted materials.



      Source link

      Copying Objects in JavaScript


      Objects are the fundamental blocks of JavaScript. An object is a collection of properties, and a property is an association between a key (or name) and a value. Almost all objects in JavaScript are instances of Object which sits on the top of the prototype chain.

      Introduction

      As you know, the assignment operator doesn’t create a copy of an object, it only assigns a reference to it, let’s look at the following code:

      let obj = {
        a: 1,
        b: 2,
      };
      let copy = obj;
      
      obj.a = 5;
      console.log(copy.a);
      // Result 
      // a = 5;
      

      The obj variable is a container for the new object initialized. The copy variable is pointing to the same object and is a reference to that object. So basically this { a: 1, b: 2, } object is saying: There are now two ways to gain access to me. You have to pass through the obj variable or the copy variable either ways you still get to me and anything you do to me via these ways (gateways) will affect me.

      Immutability is widely spoken about these days and you have to listen to this call! This method removes any form of immutability and could lead to bugs should the original object be used by another part of your code.

      The Naive Way of Copying Objects

      The naive way of copying objects is looping through the original object and copying each property one after the other. Let’s take a look at this code:

      function copy(mainObj) {
        let objCopy = {}; // objCopy will store a copy of the mainObj
        let key;
      
        for (key in mainObj) {
          objCopy[key] = mainObj[key]; // copies each property to the objCopy object
        }
        return objCopy;
      }
      
      const mainObj = {
        a: 2,
        b: 5,
        c: {
          x: 7,
          y: 4,
        },
      }
      
      console.log(copy(mainObj));
      
      

      Inherent Issues

      1. objCopy object has a new Object.prototype method different from the mainObj object prototype method, which is not what we want. We want an exact copy of the original object.
      2. Property descriptors are not copied. A “writable” descriptor with value set to be false will be true in the objCopy object.
      3. The code above only copies enumerable properties of mainObj.
      4. If one of the properties in the original object is an object itself, then it will be shared between the copy and the original making their respective properties point to the same object.

      Shallow Copying Objects

      An object is said to be shallow copied when the source top-level properties are copied without any reference and there exist a source property whose value is an object and is copied as a reference. If the source value is a reference to an object, it only copies that reference value to the target object.

      A shallow copy will duplicate the top-level properties, but the nested object is shared between the original(source) and the copy(target).

      Using Object.assign() method

      The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object.

      let obj = {
        a: 1,
        b: 2,
      };
      let objCopy = Object.assign({}, obj);
      console.log(objCopy);
      // Result - { a: 1, b: 2 }
      

      Well, this does the job so far. We have made a copy of obj. Let’s see if immutability exist:

      let obj = {
        a: 1,
        b: 2,
      };
      let objCopy = Object.assign({}, obj);
      
      console.log(objCopy); // result - { a: 1, b: 2 }
      objCopy.b = 89;
      console.log(objCopy); // result - { a: 1, b: 89 }
      console.log(obj); // result - { a: 1, b: 2 }
      

      In the code above, we changed the value of the property 'b' in objCopy object to 89 and when we log the modified objCopy object in the console, the changes only apply to objCopy. The last line of code checks that the obj object is still intact and hasn’t change. This implies that we have successfully created a copy of the source object without any references to it.

      Pitfall of Object.assign()

      Not so fast! While we successfully created a copy and everything seem to be working fine, remember we discussed shallow copying? Let’s take a look at this example:

      let obj = {
        a: 1,
        b: {
          c: 2,
        },
      }
      let newObj = Object.assign({}, obj);
      console.log(newObj); // { a: 1, b: { c: 2} }
      
      obj.a = 10;
      console.log(obj); // { a: 10, b: { c: 2} }
      console.log(newObj); // { a: 1, b: { c: 2} }
      
      newObj.a = 20;
      console.log(obj); // { a: 10, b: { c: 2} }
      console.log(newObj); // { a: 20, b: { c: 2} }
      
      newObj.b.c = 30;
      console.log(obj); // { a: 10, b: { c: 30} }
      console.log(newObj); // { a: 20, b: { c: 30} }
      
      // Note: newObj.b.c = 30; Read why..
      
      

      Why is obj.b.c = 30?

      Well, that is a pitfall of Object.assign(). Object.assign only makes shallow copies. Both newObj.b and obj.b share the same reference to the object because of individual copies were not made, instead a reference to the object was copied. Any change made to any of the object’s property applies to all references using the object. How can we fix this? Continue reading… we have a fix in the next section.

      Note: Properties on the prototype chain and non-enumerable properties cannot be copied. See here:

      let someObj = {
        a: 2,
      }
      
      let obj = Object.create(someObj, { 
        b: {
          value: 2,  
        },
        c: {
          value: 3,
          enumerable: true,  
        },
      });
      
      let objCopy = Object.assign({}, obj);
      console.log(objCopy); // { c: 3 }
      
      
      • someObj is on obj’s prototype chain so it wouldn’t be copied.
      • property b is a non-enumerable property.
      • property c has an enumerable property descriptor allowing it to be enumerable. That’s why it was copied.

      Deep Copying Objects

      A deep copy will duplicate every object it encounters. The copy and the original object will not share anything, so it will be a copy of the original. Here’s the fix to the problem we encountered using Object.assign(). Let’s explore.

      Using JSON.parse(JSON.stringify(object));

      This fixes the issue we had earlier. Now newObj.b has a copy and not a reference! This is a way to deep copy objects. Here’s an example:

      let obj = { 
        a: 1,
        b: { 
          c: 2,
        },
      }
      
      let newObj = JSON.parse(JSON.stringify(obj));
      
      obj.b.c = 20;
      console.log(obj); // { a: 1, b: { c: 20 } }
      console.log(newObj); // { a: 1, b: { c: 2 } } (New Object Intact!)
      

      Immutable: ✓

      Pitfall

      Unfortunately, this method can’t be used to copy user-defined object methods. See below.

      Copying Object methods

      A method is a property of an object that is a function. In the examples so far, we haven’t copied an object with a method. Let’s try that now and use the methods we’ve learnt to make copies.

      let obj = {
        name: 'scotch.io',
        exec: function exec() {
          return true;
        },
      }
      
      let method1 = Object.assign({}, obj);
      let method2 = JSON.parse(JSON.stringify(obj));
      
      console.log(method1); //Object.assign({}, obj)
      /* result
      {
        exec: function exec() {
          return true;
        },
        name: "scotch.io"
      }
      */
      
      console.log(method2); // JSON.parse(JSON.stringify(obj))
      /* result
      {
        name: "scotch.io"
      }
      */
      
      

      The result shows that Object.assign() can be used to copy methods while JSON.parse(JSON.stringify(obj)) can’t be used.

      Copying Circular Objects

      Circular objects are objects that have properties referencing themselves. Let’s use the methods of copying objects we’ve learnt so far to make copies of a circular object and see if it works.

      Using JSON.parse(JSON.stringify(object))

      Let’s try JSON.parse(JSON.stringify(object)):

      // circular object
      let obj = { 
        a: 'a',
        b: { 
          c: 'c',
          d: 'd',
        },
      }
      
      obj.c = obj.b;
      obj.e = obj.a;
      obj.b.c = obj.c;
      obj.b.d = obj.b;
      obj.b.e = obj.b.c;
      
      let newObj = JSON.parse(JSON.stringify(obj));
      
      console.log(newObj); 
      

      Here’s the result:

      JSON.parse(JSON.stringify(obj)) clearly doesn’t work for circular objects.

      Using Object.assign()

      Let’s try Object.assign():

      // circular object
      let obj = { 
        a: 'a',
        b: { 
          c: 'c',
          d: 'd',
        },
      }
      
      obj.c = obj.b;
      obj.e = obj.a;
      obj.b.c = obj.c;
      obj.b.d = obj.b;
      obj.b.e = obj.b.c;
      
      let newObj2 = Object.assign({}, obj);
      
      console.log(newObj2); 
      

      Here’s the result:

      Object.assign() works fine for shallow copying circular objects but wouldn’t work for deep copying. Feel free to explore the circular object tree on your browser console. I’m sure you’ll find a lot of interesting work going on there.

      Using Spread Elements ( … )

      ES6 already has rest elements for array destructuring assignment and spread elements for array literals implemented. Take a look at spread element implementation on an array here:

      const array = [
        "a",
        "c",
        "d", {
          four: 4
        },
      ];
      const newArray = [...array];
      console.log(newArray);
      // Result 
      // ["a", "c", "d", { four: 4 }]
      
      

      The spread property for object literals is currently a Stage 3 proposal for ECMAScript. Spread properties in object initializers copies own enumerable properties from a source object onto the target object. The example below shows how easy it would be to copy an object once the proposal has been accepted.

      let obj = {
        one: 1,
        two: 2,
      }
      
      let newObj = { ...z };
      
      // { one: 1, two: 2 }
      

      Note: This will just be effective for shallow copy

      Conclusion

      Copying objects in JavaScript can be quite daunting especially if you’re new to JavaScript and don’t know your way around the language. Hopefully this article helped you understand and avoid future pitfalls you may encounter copying objects. If you have any library or piece of code that achieves a better result, feel welcome to share with the community. Happy coding!



      Source link

      How to Move Objects Between Buckets in Linode's Object Storage


      Updated by Linode

      Contributed by
      Linode

      Marquee image for How to Move Objects Between Buckets in Linode's Object Storage

      Note

      Linode’s Object Storage is a globally-available, S3-compatible method for storing and accessing data. With Object Storage more widely available, you may have buckets in multiple locations, this guide shows you how to move objects between buckets quickly and easily.

      In this guide you learn how to move objects between buckets using:

      Before You Begin

      To learn how to enable Object Storage, see the How to Use Object Storage guide.

      Object Storage is similar to a subscription service. After it is enabled, you are billed at the flat rate regardless of whether or not there are active buckets on your account. Cancel Object Storage to stop billing for this flat rate.

      In all Object Storage URLs the cluster where your bucket is hosted is a part of the URL string.

      Note

      A cluster is defined as all buckets hosted by a unique URL; for example: us-east-1.linodeobjects.com, ap-south-1.linodeobjects.com, or eu-central-1.linodeobjects.com.

      Cyberduck Graphical Interface

      The easiest way to move objects between buckets is using a Graphical User Interface (GUI) such as Cyberduck. Using a GUI, you can simply drag and drop objects between buckets.

      Transfer Between Buckets in the Same Cluster

      To transfer objects within the same cluster on the same account, you need to open only one Cyberduck window.

      1. Open Cyberduck and make a connection to access your buckets as described in How to Use Linode Object Storage.

      2. Expand the two buckets you want to transfer objects between by clicking the down arrow to the left of the folders.

      3. Locate the object you want to transfer.

      4. Drag the item from the source location to the destination.

        Drag a File to Move

      5. Select multiple items or folders and drag the group to the destination.

        Drag Multiple Files to Move

      Transfer Between Buckets in Different Clusters

      To transfer objects between two clusters, whether they are on the same account or not, you need to open two separate Cyberduck widows so that you can make two separate connections.

      Note

      Transferring objects between two different connections creates a copy of the object(s). If you don’t want the original files in the source bucket, you need to delete them after the transfer.

      1. Open Cyberduck, click the File menu and select New Browser. A second interface window appears where you can create another connection.

      2. In the first window, connect to the source bucket and locate the object you want to copy.

      3. In the second window, connect to the destination bucket and navigate to the location you want to place a copy of the object.

      4. Drag the object from the source to the destination.

        Select Objects to Move Between Cyberduck Windows

      Note

      You can easily copy multiple items, folders, or buckets by selecting everything you want to move and dragging the group. If you move a bucket to another bucket, it creates a folder with that bucket name.

      Cyberduck CLI

      You can also use the Cyberduck CLI, duck, to move objects from one bucket to another using the command line. The file transfer tool duck, is available for Linux, macOS, and Windows. To transfer using duck, you need the access keys that you generated for the source and destination buckets.

      1. Install duck using the instructions for your platform.

      2. Use the access keys and bucket names in the following command to move objects between buckets:

        duck --copy s3://[email protected]$bucket_source/source_object_file_name s3://[email protected]$bucket_destination/destination_object_file_name
        

        After issuing this command, you may be asked for login information.

      Note

      The bucket source and destination names are the fully qualified names including the cluster name, for example: us-east-1.linodeobjects.com/example_bucket.

      More Information

      You may wish to consult the following resources for additional information on this topic. While these are provided in the hope that they will be useful, please note that we cannot vouch for the accuracy or timeliness of externally hosted materials.

      This guide is published under a CC BY-ND 4.0 license.



      Source link