Which way is best for creating an object in JavaScript? Is `var` necessary before an object property?

前端 未结 8 1841
无人共我
无人共我 2020-11-27 08:59

So far I saw three ways for creating an object in JavaScript. Which way is best for creating an object and why?

I also saw that in all of these examples the keyword

相关标签:
8条回答
  • 2020-11-27 09:19

    I guess it depends on what you want. For simple objects, I guess you could use the second methods. When your objects grow larger and you're planning on using similar objects, I guess the first method would be better. That way you can also extend it using prototypes.

    Example:

    function Circle(radius) {
        this.radius = radius;
    }
    Circle.prototype.getCircumference = function() {
        return Math.PI * 2 * this.radius;
    };
    Circle.prototype.getArea = function() {
        return Math.PI * this.radius * this.radius;
    }
    

    I am not a big fan of the third method, but it's really useful for dynamically editing properties, for example var foo='bar'; var bar = someObject[foo];.

    0 讨论(0)
  • 2020-11-27 09:22

    While many people here say there is no best way for object creation, there is a rationale as to why there are so many ways to create objects in JavaScript, as of 2019, and this has to do with the progress of JavaScript over the different iterations of EcmaScript releases dating back to 1997.

    Prior to ECMAScript 5, there were only two ways of creating objects: the constructor function or the literal notation ( a better alternative to new Object()). With the constructor function notation you create an object that can be instantiated into multiple instances (with the new keyword), while the literal notation delivers a single object, like a singleton.

    // constructor function
    function Person() {};
    
    // literal notation
    var Person = {};
    

    Regardless of the method you use, JavaScript objects are simply properties of key value pairs:

    // Method 1: dot notation
    obj.firstName = 'Bob';
    
    // Method 2: bracket notation. With bracket notation, you can use invalid characters for a javascript identifier.
    obj['lastName'] = 'Smith';
    
    // Method 3: Object.defineProperty
    Object.defineProperty(obj, 'firstName', {
        value: 'Bob',
        writable: true,
        configurable: true,
        enumerable: false
    })
    
    // Method 4: Object.defineProperties
    Object.defineProperties(obj, {
      firstName: {
        value: 'Bob',
        writable: true
      },
      lastName: {
        value: 'Smith',
        writable: false
      }
    });
    

    In early versions of JavaScript, the only real way to mimic class-based inheritance was to use constructor functions. the constructor function is a special function that is invoked with the 'new' keyword. By convention, the function identifier is capitalized, albiet it is not required. Inside of the constructor, we refer to the 'this' keyword to add properties to the object that the constructor function is implicitly creating. The constructor function implicitly returns the new object with the populated properties back to the calling function implicitly, unless you explicitly use the return keyword and return something else.

    function Person(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    
        this.sayName = function(){
            return "My name is " + this.firstName + " " + this.lastName;
        }
    } 
    
    var bob = new Person("Bob", "Smith");
    bob instanceOf Person // true
    

    There is a problem with the sayName method. Typically, in Object-Oriented Class-based programming languages, you use classes as factories to create objects. Each object will have its own instance variables, but it will have a pointer to the methods defined in the class blueprint. Unfortunately, when using JavaScript's constructor function, every time it is called, it will define a new sayName property on the newly created object. So each object will have its own unique sayName property. This will consume more memory resources.

    In addition to increased memory resources, defining methods inside of the constructor function eliminates the possibility of inheritance. Again, the method will be defined as a property on the newly created object and no other object, so inheritance cannot work like. Hence, JavaScript provides the prototype chain as a form of inheritance, making JavaScript a prototypal language.

    If you have a parent and a parent shares many properties of a child, then the child should inherit those properties. Prior to ES5, it was accomplished as follows:

    function Parent(eyeColor, hairColor) {
        this.eyeColor = eyeColor;
        this.hairColor = hairColor;
    }
    
    Parent.prototype.getEyeColor = function() {
      console.log('has ' + this.eyeColor);
    }
    
    Parent.prototype.getHairColor = function() {
      console.log('has ' + this.hairColor);
    }
    
    function Child(firstName, lastName) {
      Parent.call(this, arguments[2], arguments[3]);
      this.firstName = firstName;
      this.lastName = lastName;
    }
    
    Child.prototype = Parent.prototype;
    
    var child = new Child('Bob', 'Smith', 'blue', 'blonde');
    child.getEyeColor(); // has blue eyes
    child.getHairColor(); // has blonde hair
    

    The way we utilized the prototype chain above has a quirk. Since the prototype is a live link, by changing the property of one object in the prototype chain, you'd be changing same property of another object as well. Obviously, changing a child's inherited method should not change the parent's method. Object.create resolved this issue by using a polyfill. Thus, with Object.create, you can safely modify a child's property in the prototype chain without affecting the parent's same property in the prototype chain.

    ECMAScript 5 introduced Object.create to solve the aforementioned bug in the constructor function for object creation. The Object.create() method CREATES a new object, using an existing object as the prototype of the newly created object. Since a new object is created, you no longer have the issue where modifying the child property in the prototype chain will modify the parent's reference to that property in the chain.

    var bobSmith = {
        firstName: "Bob",
        lastName: "Smith",
        sayName: function(){
          return "My name is " + this.firstName + " " + this.lastName;
        }
    }
    
    var janeSmith = Object.create(bobSmith, {
        firstName : {  value: "Jane" }
    })
    
    console.log(bobSmith.sayName()); // My name is Bob Smith
    console.log(janeSmith.sayName()); // My name is Jane Smith
    janeSmith.__proto__ == bobSmith; // true
    janeSmith instanceof bobSmith; // Uncaught TypeError: Right-hand side of 'instanceof' is not callable. Error occurs because bobSmith is not a constructor function.
    

    Prior to ES6, here was a common creational pattern to utilize function constructors and Object.create:

    const View = function(element){
      this.element = element;
    }
    
    View.prototype = {
      getElement: function(){
        this.element
      }
    }
    
    const SubView = function(element){
      View.call(this, element);
    }
    
    SubView.prototype = Object.create(View.prototype);
    

    Now Object.create coupled with constructor functions have been widely used for object creation and inheritance in JavaScript. However, ES6 introduced the concept of classes, which are primarily syntactical sugar over JavaScript's existing prototype-based inheritance. The class syntax does not introduce a new object-oriented inheritance model to JavaScript. Thus, JavaScript remains a prototypal language.

    ES6 classes make inheritance much easier. We no longer have to manually copy the parent class's prototype functions and reset the child class's constructor.

    // create parent class
    class Person {
      constructor (name) {
        this.name = name;
      }
    }
    
    // create child class and extend our parent class
    class Boy extends Person {
      constructor (name, color) {
        // invoke our parent constructor function passing in any required parameters
        super(name);
    
        this.favoriteColor = color;
      }
    }
    
    const boy = new Boy('bob', 'blue')
    boy.favoriteColor; // blue
    

    All in all, these 5 different strategies of Object Creation in JavaScript coincided the evolution of the EcmaScript standard.

    0 讨论(0)
  • 2020-11-27 09:23

    Of course there is a best way.Objects in javascript have enumerable and nonenumerable properties.

    var empty = {};
    console.log(empty.toString);
    // . function toString(){...}
    console.log(empty.toString());
    // . [object Object]
    

    In the example above you can see that an empty object actually has properties.

    Ok first let's see which is the best way:

    var new_object = Object.create(null)
    
    new_object.name = 'Roland'
    new_object.last_name = 'Doda'
    //etc
    
    console.log("toString" in new_object) //=> false
    

    In the example above the log will output false.

    Now let's see why the other object creation ways are incorrect.

    //Object constructor
    var object = new Object();
    
    console.log("toString" in object); //=> true
    
    //Literal constructor
    var person = { 
      name : "Anand",
      getName : function (){
       return this.name
      } 
    } 
    
    console.log("toString" in person); //=> true
    
    //function Constructor
    function Person(name){
      this.name = name
      this.getName = function(){
        return this.name
      } 
    }
    
    var person = new Person ('landi')
    
    console.log("toString" in person); //=> true
    
    //Prototype
    function Person(){};
    
    Person.prototype.name = "Anand";
    
    console.log("toString" in person); //=> true
    
    //Function/Prototype combination
    function Person2(name){
      this.name = name;
    } 
    
    Person2.prototype.getName = function(){
      return this.name
    }
    
    var person2 = new Person2('Roland')
    
    console.log("toString" in person2) //=> true
    

    As you can see above,all examples log true.Which means if you have a case that you have a for in loop to see if the object has a property will lead you to wrong results probably.

    Note that the best way it is not easy.You have to define all properties of object line by line.The other ways are more easier and will have less code to create an object but you have to be aware in some cases. I always use the "other ways" by the way and one solution to above warning if you don't use the best way is:

     for (var property in new_object) {
      if (new_object.hasOwnProperty(property)) {
        // ... this is an own property
      }
     }
    
    0 讨论(0)
  • 2020-11-27 09:24

    Majorly there are 3 ways of creating Objects-

    Simplest one is using object literals.

    const myObject = {}
    

    Though this method is the simplest but has a disadvantage i.e if your object has behaviour(functions in it),then in future if you want to make any changes to it you would have to change it in all the objects.

    So in that case it is better to use Factory or Constructor Functions.(anyone that you like)

    Factory Functions are those functions that return an object.e.g-

    function factoryFunc(exampleValue){
       return{
          exampleProperty: exampleValue 
       }
    }
    

    Constructor Functions are those functions that assign properties to objects using "this" keyword.e.g-

    function constructorFunc(exampleValue){
       this.exampleProperty= exampleValue;
    }
    const myObj= new constructorFunc(1);
    
    0 讨论(0)
  • 2020-11-27 09:26

    There is various way to define a function. It is totally based upon your requirement. Below are the few styles :-

    1. Object Constructor
    2. Literal constructor
    3. Function Based
    4. Protoype Based
    5. Function and Prototype Based
    6. Singleton Based

    Examples:

    1. Object constructor
    var person = new Object();
    
    person.name = "Anand",
    person.getName = function(){
      return this.name ; 
    };
    
    1. Literal constructor
    var person = { 
      name : "Anand",
      getName : function (){
       return this.name
      } 
    } 
    
    1. function Constructor
    function Person(name){
      this.name = name
      this.getName = function(){
        return this.name
      } 
    } 
    
    1. Prototype
    function Person(){};
    
    Person.prototype.name = "Anand";
    
    1. Function/Prototype combination
    function Person(name){
      this.name = name;
    } 
    Person.prototype.getName = function(){
      return this.name
    } 
    
    1. Singleton
    var person = new function(){
      this.name = "Anand"
    } 
    

    You can try it on console, if you have any confusion.

    0 讨论(0)
  • 2020-11-27 09:31

    There are a many ways to create your objects in JavaScript. Using a constructer function to create an object or object literal notation is using alot in JavaScript. Also creating an instance of Object and then adding properties and methods to it, there are three common ways to do create objects in JavaScript.

    Constructer functions

    There are built-in constructer functions that we all may use them time to time, like Date(), Number(), Boolean() etc, all constructer functions start with Capital letter, in the meantime we can create custom constructor function in JavaScript like this:

    function Box (Width, Height, fill) {  
      this.width = Width;  // The width of the box 
      this.height = Height;  // The height of the box 
      this.fill = true;  // Is it filled or not?
    }  
    

    and you can invoke it, simply using new(), to create a new instance of the constructor, create something like below and call the constructor function with filled parameters:

    var newBox = new Box(8, 12, true);  
    

    Object literals

    Using object literals are very used case creating object in JavaScript, this an example of creating a simple object, you can assign anything to your object properties as long as they are defined:

    var person = { 
        name: "Alireza",
        surname: "Dezfoolian"
        nose: 1,  
        feet: 2,  
        hands: 2,
        cash: null
    };  
    

    Prototyping

    After creating an Object, you can prototype more members to that, for example adding colour to our Box, we can do this:

    Box.prototype.colour = 'red';
    
    0 讨论(0)
提交回复
热议问题