No Object.defineProperty you will be out

 
Object.defineProperty  , as the name suggests, defines a property for an object . In js we can define properties in the following ways
// (1) define someOne property name
someOne.name = 'cover';
//or use (2) 
someOne['name'] = 'cover';
// or use (3) defineProperty
Object.defineProperty(someOne, 'name', {
    value : 'cover'
})

From the above, it seems that using Object.defineProperty is very troublesome, so why does such a method exist?

With doubt, let's take a look at the definition of Object.defineProperty.


what is Object.defineProperty

The Object.defineProperty() method defines a new property directly on an object, or modifies an exisiting property on an object, and returns the object.

From the above, we can use Object.definePropertythis method to define a new property directly on an object, or modify an existing property. Eventually this method will return the object.

grammar

Object.defineProperty(object, propertyname, descriptor)

parameter

  • object  Required. The object on which to add or modify properties. This may be a native JavaScript object (ie user-defined or built-in) or a DOM object. propertyname  Required. A string containing the property name. descriptor is  required. property descriptor. It can target data properties or accessor properties.
property state setting

The parameters of descriptor are worthy of our attention. The values ​​that can be set for this property are:

  • [value] The value of the property, the default is undefined. 【writable】Whether the property is writable, if it is set to false, any operation to rewrite the property will be invalid (but no error will be reported). For the property defined directly on the object like the previous example, the default value of this property is the property is true.
var someOne = { };
Object.defineProperty(someOne, "name", {
    value:"coverguo" , //由于设定了writable属性为false 导致这个量不可以修改
    writable: false 
});  
console.log(someOne.name); // 输出 coverguo
someOne.name = "linkzhu";
console.log(someOne.name); // 输出coverguo

  • [configurable]] If false, any attempt to delete the target property or modify the following properties (writable, configurable, enumerable) of the property will be invalidated. For properties defined directly on the object like in the previous example, this property is the property The default value is true. .
var someOne = { };
Object.defineProperty(someOne, "name", {
    value:"coverguo" ,
    configurable: false 
});  
delete someOne.name; 
console.log(someOne.name);// 输出 coverguo
someOne.name = "linkzhu";
console.log(someOne.name); // 输出coverguo

  • [enumerable] Whether it can be traversed in the for-in loop or listed in Object.keys. For properties defined directly on the object like in the previous example, this property defaults to true.

Note that  when calling the Object.defineProperty() method, if not specified, the default values ​​of the configurable, enumerable, and writable properties are all false, which 对于像前面例子中直接在对象上定义的属性,这个特性默认值为为 true。does not conflict with what was said before, as shown in the following code:

//调用Object.defineProperty()方法时,如果不指定
var someOne = { };
someOne.name = 'coverguo';
console.log(Object.getOwnPropertyDescriptor(someOne, 'name'));
//输出 Object {value: "coverguo", writable: true, enumerable: true, configurable: true}

//直接在对象上定义的属性,这个特性默认值为为 true
var otherOne = {};
Object.defineProperty(otherOne, "name", {
    value:"coverguo" 
});  
console.log(Object.getOwnPropertyDescriptor(otherOne, 'name'));
//输出 Object {value: "coverguo", writable: false, enumerable: false, configurable: false}

  • [get] Once the target object accesses the property, this method will be called and the result will be returned. Defaults to undefined. [set] This method is called once the target object sets the property. Defaults to undefined.

From the above, we can know that we can define and control some special properties by using Object.defineProperty, such as whether the property is readable, whether the property is enumerable, and even modify the modifier (setter) and getter (getter) of the property )

What scenarios and places are suitable for using special attributes?


practical use

In some frameworks, such as vue, express, qjs, etc., the use of Object.defineProperty is often seen. How are these frameworks used?

Data 'two-way binding' implementation in MVVM

Most mvvm frameworks such as vue and qjs (angular uses dirty processing) implement data binding through Object.defineProperty. For a more detailed explanation, I will explain it to you in the next article. The following paragraphs will not be expanded. (Don't throw bricks...)

Optimize the way to get and modify properties of objects

What does this optimization object mean by acquiring and modifying properties? In the past, we did this when setting the dom node transform.

//加入有一个目标节点, 我们想设置其位移时是这样的
var targetDom = document.getElementById('target');
var transformText = 'translateX(' + 10 + 'px)';
targetDom.style.webkitTransform = transformText;
targetDom.style.transform = transformText;

From the above, you can see that if the page needs many animations, it is very painful for us to write the transform property like this. (┬_┬)

But if we pass Object.defineProperty, we can

//这里只是简单设置下translateX的属性,其他如scale等属性可自己去尝试

Object.defineProperty(dom, 'translateX', {
set: function(value) {
         var transformText = 'translateX(' + value + 'px)';
        dom.style.webkitTransform = transformText;
        dom.style.transform = transformText;
}
//这样再后面调用的时候, 十分简单
dom.translateX = 10;
dom.translateX = -10;
//甚至可以拓展设置如scale, originX, translateZ,等各个属性,达到下面的效果
dom.scale = 1.5;  //放大1.5倍
dom.originX = 5;  //设置中心点X
}

The above is just a simple version, not the most reasonable way of writing, but mainly to illustrate the specific intention and method

If you are interested in learning more, you can look at the following library: https://github.com/AlloyTeam/AlloyTouch/blob/master/transform.js

Added information on property acquisition and modification

For example, in Express 4.0, this version removes some old middleware. In order to allow users to better discover, it has the following code. By modifying the get attribute method, users can throw an error and bring the custom error message.

[
  'json',
  'urlencoded',
  'bodyParser',
  'compress',
  'cookieSession',
  'session',
  'logger',
  'cookieParser',
  'favicon',
  'responseTime',
  'errorHandler',
  'timeout',
  'methodOverride',
  'vhost',
  'csrf',
  'directory',
  'limit',
  'multipart',
  'staticCache',
].forEach(function (name) {
  Object.defineProperty(exports, name, {
    get: function () {
      throw new Error('Most middleware (like ' + name + ') is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.');
    },
    configurable: true
  });
});

Other uses such as setting constants. . .


compatible

 

 

Finally, note that Object.defineProperty is an ES5 property , which is fine in most scenarios, but cannot be used in some scenarios such as IE8 and below.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326271469&siteId=291194637