when do you use Object.defineProperty()

前端 未结 10 2341
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-08 01:31

I\'m wondering when I should use

Object.defineProperty

to create new properties for an object. I\'m aware that I\'m able to set things lik

相关标签:
10条回答
  • 2020-12-08 02:27

    One neat use case I have seen for defineProperty is for libraries to provide an error property to the user which, if it's not accessed within a certain interval you would throw yourself. For example:

    let logErrorTimeoutId = setTimeout(() => {
      if (error) {
        console.error('Unhandled (in <your library>)', error.stack || error);
      }
    }, 10);
    
    Object.defineProperty(data, 'error', {
        configurable: true,
        enumerable: true,
        get: () => {
          clearTimeout(logErrorTimeoutId);
          return error;
        },
      });
    

    Source for this code: https://github.com/apollographql/react-apollo/blob/ffffd3d8faabf135dca691d20ce8ab0bc24ccc414e/src/graphql.tsx#L510

    0 讨论(0)
  • 2020-12-08 02:31

    A really good reason for using Object.defineProperty is that it lets you loop through a function in an object as a computed property, which executes the function instead of returning the function's body.

    For example:

    var myObj = {};
    
    myObj.width = 20;
    myObj.height = 20;
    
    Object.defineProperty(myObj, 'area', {
        get: function() {
            return this.width*this.height;
        },
        enumerable: true
    });
    
    for (var key in myObj) {
      if (myObj.hasOwnProperty(key)) {
        console.log(key + " -> " + myObj[key]);
      }
    }
    //width -> 20, height -> 20, area -> 400
    

    Versus adding the function as a property to an object literal:

    var myObj = {};
    
    myObj.width = 20;
    myObj.height = 20;
    
    myObj.area = function() {
           return this.width*this.height;
        };
    
    for (var key in myObj) {
      if (myObj.hasOwnProperty(key)) {
        console.log(key + " -> " + myObj[key]);
      }
    }
    // width -> 20, height -> 20, area -> function() { return this.width*this.height;}
    

    Make sure you set the enumerable property to true in order to loop through it.

    0 讨论(0)
  • 2020-12-08 02:31

    A good use is when you need to do some interception or apply a classical Observer/Observable pattern in a elegant way:

    https://www.monterail.com/blog/2016/how-to-build-a-reactive-engine-in-javascript-part-1-observable-objects

    0 讨论(0)
  • 2020-12-08 02:33

    Features like 'enumerable' are rarely used in my experience. The major use case is computed properties:

    var myObj = {};
    
    myObj.width = 20;
    myObj.height = 20;
    
    Object.defineProperty(myObj, 'area', {
        get: function() {
            return this.width*this.height;
        }
    });
    console.log(myObj.area);
    
    0 讨论(0)
提交回复
热议问题