程序员

JavaScript神奇的监听属性Object.definePr

2017-10-26  本文已影响0人  Rubin666
在javascript的类中,可以用 __ defineGetter __和 __ defineSetter __控制成员变量的Get和Set行为。
image.png
在对象定义后给对象添加getter或setter方法要通过两个特殊的方法defineGetterdefineSetter。这两个函数要求第一个是getter或setter的名称,以string给出,第二个参数是作为getter或setter的函数。
例如我们给Date对象添加一个year属性:
Date.prototype.__defineGetter__('year', function() {return this.getFullYear();});     
Date.prototype.__defineSetter__('year', function(y) {this.setFullYear(y)});     

var now = new Date;     
alert(now.year);     
now.year = 2006;     
alert(now);  

不过,这两个属性已经被废弃,所以并不推荐大家去使用。咱们今天的主角是defineProperty。

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
语法:Object.defineProperty(obj, prop, descriptor)

obj

需要被操作的目标对象

prop

目标对象需要定义或修改的属性的名称。

descriptor

将被定义或修改的属性的描述符。

返回值

被传递给函数的对象。

目前常用示例: Setters 和 Getters

function Archiver() {
  var temperature = null;
  var archive = [];

  Object.defineProperty(this, 'temperature', {
    get: function() {
      console.log('get!');
      return temperature;
    },
    set: function(value) {
      temperature = value;
      archive.push({ val: temperature });
    }
  });

  this.getArchive = function() { return archive; };
}

var arc = new Archiver();
arc.temperature; // 'get!'
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]

or

var pattern = {
    get: function () {
        return 'I alway return this string,whatever you have assigned';
    },
    set: function () {
        this.myname = 'this is my name string';
    }
};


function TestDefineSetAndGet() {
    Object.defineProperty(this, 'myproperty', pattern);
}


var instance = new TestDefineSetAndGet();
instance.myproperty = 'test';

// 'I alway return this string,whatever you have assigned'
console.log(instance.myproperty);
// 'this is my name string'
console.log(instance.myname);

实际运用

在一些框架,如vue、express、qjs等,经常会看到对Object.defineProperty的使用。那这些框架是如何使用呢?

MVVM中数据‘双向绑定’实现

如vue,qjs等大部分mvvm框架(angular用的是脏处理)都是通过Object.defineProperty来实现数据绑定的 下面篇幅先不展开。(别扔砖。。。)

兼容

最后注意下,Object.defineProperty是ES5的属性,大部分场景使用是没问题的,移动端可以放心用, 但在一些场景如IE8以下是使用不到的哈。

上一篇下一篇

猜你喜欢

热点阅读