JavaScript权威指南笔记(3)

如果o继承了x属性,而x属性恰好是一个存取器属性(参见6.6)那么如果设置o.x=2是不会创建属性的,也不会修改父类的值,只会修改本类的值。

var a ={

  x:1,

  get r(){return this.x},

  set r(value){this.x = value}

}

var b = Object.create(a);

b.r = 2;  //这个操作修改了b中x的值

b.x    //2

a.x    //因为b中的操作只会修改b的值,所以a.x值不会变。

 

检测属性是否在对象中。

in/ !==:()

属性名 in 对象

var o = {x:1}

"x" in o  //true

o.x !== undefined; //true

"y" in o //false

o.y !== o //false

"toString" in o //true  o继承toString属性

o.toString !== o //true  o继承toString属性

有一种情况in和!==不同,即属性值为undefined的时候,"x" in o 为true o.x !== undefined 为false。

检测属性是否为对象的自有属性(非继承)

hasOwnProperty():

o.hasOwnProperty("x"); //true

o.hasOwnProperty("y"); //false

o.hasOwnProperty("toString") //false  toString是继承属性

检测属性是否为对象的自有属性,并且属性是否为可枚举的

propertyIsEnumerable():

o.propertyIsEnumerable("x"); //true o有一个可枚举的自有属性x

object.prototype.propertyIsEnumerable("toString"); //false:不可枚举

见128页6.4

------------------------------------------------16.10.13 结束---------------------------------------------------------------------------

-----------------------------------------------16.10.15 开始---------------------------------------------------------------------------

枚举属性

for/in循环可以遍历继承来的属性

见130页上

 

Object.getOwnPropertyNames(o); // 获取对象的所有自有属性。

见132页上

-----------------------------------------------16.10.15 结束---------------------------------------------------------------------------


-----------------------------------------------16.10.16 开始---------------------------------------------------------------------------

getter和setter

和数据属性不同,由getter和setter定义的为存取器属性

var o = {

  x:1,

  get r(){ return this.x},

  set r(value)  { this.x = value},

}

o.r  //1

o.r = 2;

o.r  //2

此时r这个属性是可读可写的,如果我们将set去掉。不管怎么给o.r赋值,o.r的属性一直都是不变的。但是在非严格模式下是不会报错的。同理,去掉get以后就无法获取属性值,o.r的值就为undefined。

见132页6.6

 

var a= {

  $n = 0  //$符号暗示这个属性是一个私有属性

}

a.n   //undefined

见134页上

 


属性的特性(API对库开发者来说非常重要)因为:

1、 可以通过这些API给原型对象添加方法,并将它们设置成不可枚举的,这让它们看起来更像内置方法。

2、可以通过这些API给对象定义不能修改或删除的属性,借此“锁定”这个对象。

 

属性的4个特性(‘属性描述符’对象):

1、数据属性:值(value)、可写性(writable)、可枚举性(enumerable)、可配置性(configurable)

2、存取器属性:读取(get)、写入(set)、可枚举性、可配置性

通过Object.getOwnPropertyDescriptor()可以获得某个对象特定属性的属性描述符:

Object.getOwnPropertyDescriptor({x:1},"x")  //  返回{value:1, writable:true, enumerable:true, configurable:true}

Object.getOwnPropertyDescriptor(o,"r")  //查询上面定义的o的r属性,返回{get:/*func*/, set:/*func*/, enumerable:true, configurable:true}

如果属性不存在,或者为继承属性,则返回undefined

见134页6.7

 

设置属性特性:

var o = {}

Object.defineProperty(o,"x",{ value:1,

                writable:true,

                enumerable:false,

                configurable:true});

//给o对象添加一个不可枚举的数据属性x,并赋值为1

Object.keys(o)  //因为o的x属性是不可枚举的,所以返回空数组[]

Object.defineProperty(o,"x",{writable:false});  //将x属性变成只读

o.x = 2  //操作失败,但在非严格模式中不会报错

o.x   //为1

Object.defineProperty(o,"x",{value:2})  //因为属性依然是可配置的,所以可以通过这种方法进行修改

Object.defineProperty(o,"x",{get:function(){return 0;}});  //还可以将x从数据属性改为存取器属性

o.x  //输出0

从上面可以看出来Object.defineProperty()的属性描述符参数对象不需要包含所有的4个特性,如果是新创建的,那么默认的就是false或者undefined。如果是修改的,那么就只修改设置的。

注意:这个方法要么修改已有属性,要么新建自有属性,并不能修改继承属性。

见135页中下

 

同时修改或创建多个属性:

var o = {};

Object.defineProperties(o,{

  x:{value:1,  writable:true,  enumerable:true,  configurable:true},

  y:{value:2,  writable:true,  enumerable:true,  configurable:true},

  r:{

    get:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},

    enumerable:true,

    configurable:true

  }

});

见136页中

 

Object.defineProperty()和Object.defineProperties()使用规则:

1、如果对象是不可扩展的(参见6.8.3节),则可以编辑已有的自有属性,但不能给它添加新属性。

2、如果属性是不可配置的,则不能修改它的可配置性和可枚举性。

3、如果存取器属性是不可配置的,则不能修改其getter和setter方法,也不能将它转换为数据属性。

4、如果数据属性是不可配置的,则不能将它转换为存取器属性。

5、如果数据属性是不可配置的,则不能将它的可写性从false修改为true,但可以从true修改为false。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/0c0315b1d5014578b6e4d7ccca03f611.html