首页 > 代码库 > 《JavaScript高级程序设计 第二版》理解对象

《JavaScript高级程序设计 第二版》理解对象

声明:这类属于学习笔记,主要是摘录书中内容,比较少的整理。内容经常是跳跃的,建议您阅读书本,收益更大。


ECMA-262把对象定义为“无序属性的集合,其属性可以包含基本值,对象或者函数”

对象时一组没有特定顺序的值,每个属性或方法都有一个名字,每个名字都映射一个值。

每个对象都是基于一个引用类型创建的,这个引用类型可以是第5章讨论的原生类型,也可以是开发人员定义的类型

常规的创建对象的方法是通过Object这个内置对象来进行创建出一个实例,然后再給其添加属性和方法

var person=new Object();person.name="nico";person.age=22;person.sayName=function(){     alert(this.name)  }

后来大家逐渐使用对象字面量来创建对象

var person={    name:"nico",    age:22,    sayname:function(){         alert(this.name)     }};

属性

在ECMA-262第五版定义  只有内部才用的特性时,描述了属性的各种特征。

ECMA-262定义这些特性是为了JavaScript引擎用的,因此在JavaScript中不能直接访问他们。

为了表示是内部值,该规范将他们放在了两对方括号中例如 [[Enumerable]]

 

数据属性:包含一个数据值得位置,在这个为之可以读取和写入值,有4个可以描述其行为的特性

  • [[Configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特征性,可以在对象上直接定义的属性,或者将其修改为访问器属性,默认为true
  • [[Enumerable]]:能否通过for-in循环返回属性,可以在对象上直接定义的属性,默认true
  • [[Writable]]:表示能否修改属性的值,可以在对象上直接定义的属性,默认true
  • [[Value]]:包含这个属性的数据值。读取属性的时候,从这个位置读,写入属性的时候,在这个为之写,默认是undefined。

如果没有对这些特性值制定,那么会是默认的。有一点,要修改这些,必须调用Object.defineProperty()方法,接受三个参数

  • 属性所在的对象
  • 属性的名字
  • 描述符对象(必须是上面介绍的4个中1~4个)

如下

var person={ };Object.defineProperty(person,"name", {    writable:false,    value:"kobe"});console.log(person.name); //kobeperson.name="mike";console.log(person.name); //kobe

然后这里要注意,如果修改了Configurable设置了false,那么以后这个对象的这个属性就不能改改回来了,会发生错误。除了writable可以改以外。而且当不指定的之后,这些值会从默认的true变为false。好在我们多数情况是没有必要使用这些属性的。

 

访问器属性

不包括数据值:他们包含一堆getter和setter函数(这两个函数不是必须的)。读取访问器属性时,调用getter,写入时会调用setter。

  • [[Configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特征性,可以在对象上直接定义的属性,或者将其修改为访问器属性,默认为true
  • [[Enumerable]]:能否通过for-in循环返回属性,可以在对象上直接定义的属性,默认true
  • [[Get]]:在读取时候调用的函数。默认是undefined
  • [[Set]]:在写入时候调用的函数,默认是undefined

同样的也是不能直接访问,必须通过和上面一样的函数来访问

var book={    _year:2004,    edition:1};Object.defineProperty(book, "year", {    get:function(){        return this._year;    },    set:function(newValue){        if (newValue>2004) {            this._year=newValue;            this.edition += newValue-2004;        }    }});book.year=2006;console.log(book.edition); //3

你可以不同时指定,如果另一个没有指定,则意味着不可用。例如只制定了setter,表示不可读;反之

在此之前,访问器属性使用的是_defineGetter_ 和 _defineSetter_,前面的Object换成具体对象,如book._defineGetter_(),2个参数,省去了前面的第一个参数

定义多个属性 Object.defineProperties(),接受2个对象参数,第一个参数是要添加和修改属性的对象,第二个与第一个对象中药添加或修改的一一对应

读取属性的特性:Object.getOwnPropertyDescriptor();接受2个参数,属性所在的对象,和要读取的属性名,返回的是一个对象

 

《JavaScript高级程序设计 第二版》理解对象