肉烂在锅里

个人站

我是软件研发中心培训主管,我喜欢看动漫,学习web前端开发。


Javascript中的控制属性的行为方式/数据属性&访问器属性

Javascript中的控制属性的行为方式/数据属性&访问器属性

  最近发现了一个有趣的东西,让我了解了属性的属性(这么说不知道贴不贴切)。 这些小东西看上去可能并不是很重要,并且大多数情况可能都不会用到这样高级的属性。但是,我认为了解这些东西还是有的,像是在我们枚举某个对象的一些属性的时候,我们可能不希望让所有的属性都出现在我们的眼前,或是我们希望这个属性不会被不小心的删除或者重置。这些 小属性就派上了用场。这些[[属性]]是为了实现Javascript引擎用的,但是却不能被Javascript引擎直接访问, 而是需要通过特定的函数才能访问。为了表示这些属性是内布值,ECMA-262规范把他们放在了两对方括号中。

  ECMAScript中有两种属性:数据属性访问器属性

数据属性

  我认为数据属性就是那些保存着一些值的属性,他们的最大特点是拥有[[Value]],属性 这个属性中保存着值。
  数据属性包含着四个属性:
     [[Configurable]]:false就不会被delete所删除,也不能把他更改为访问器属性。
     [[Enumerable]]:false不能通过for-in循环返回。
     [[Writeable]]:false则不能修改属性的值。
     [[Value]]:这个属性中保存的就是这个属性的值。

访问器属性

  访问器属性和数据属性的区别在于,他们并不含有特定的数据值, 因此,他们并不含有[[Value]]属性,他们的“值”只是一对儿get和set函数,在读取访问器属 性的时候会调用get函数,在写入数据的时候则会调用set函数。这就可以让我们 很方便的在为函数写入值的时候自动执行一些逻辑,而不用在另创建一个函数来根据属性的值 来执行其他的逻辑。

  var book = {};
  Object.defineProperties(book,{
      year:{
          enumerable:true,
          /**
           在ECM5中enumerable属性的默认值是true,但是在ECM6中,默认值是false,
           (真的很烦啊,标准变来变去的,看来数据属性和访问器属性被特殊点名的时候,
           希望enumerable属性为false的时候占大多数啊)
          **/
          configurable:false, //设置year属性不能被delete删除
          writable:true,
          value:2018,
      },
      edition:{
          enumerable:false,  //设置edition属性不能被for in循环所返回
          writable:true,
          value:1
      }
  });
  delete book.year;
  console.log(book.year); //依旧输出2018

  for(var x in book){
      console.log(book[x]); //并没有输出1
  }

另一段代码展示访问器属性,set和get

var book = {};
Object.defineProperties(book,{
    _year:{
        enumerable:true, //在ECM5中enumerable属性的默认值是true,但是在ECM6中,默认值是false
        configurable:false, //设置year属性不能被delete删除
        writable:true,
        value:2018,
    },
    edition:{
        enumerable:false,  //设置edition属性不能被for in循环所返回
        writable:true,
        value:0
    },
    year:{
        get:function(){
            return this._year;
        },
        set:function(newYear){
            if(newYear >= this._year){
                this.edition = newYear - this._year;
                this._year = newYear;
            }
        }

    }
});

console.log(book.year + "||" + book.edition); //输出2018 || 0
book.year = 2019;
console.log(book.year + "||" + book.edition); //输出2019 || 1

值得注意的是,上面的代码,year属性不在是原来的数据属性_year(一般只有对象内部才能访问到的属性前 面会加一个下划线),成为了一个新的访问器属性。在这个访问器属性中,我们更改了新的edition,同时更 改了_year。如果不这样做,我们就需要一个新的单独的函数来更新edition._year。)

读取属性的特性(这里才想起来,叫做属性的特性应该更合适)

  很简单,只要使用ECMAScript5的Object.getOwnPropertyDescriptor()方法即可。

var descriptor = Object.getOwnPropertyDescriptor("book","_year");
console.log(descriptor.value + "||" + descriptor.configurable);
//2018||false

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦