JavaScript高级程序设计(第3版)学习笔记10 再访

(1)对象属性和特性

  什么是属性(Property),什么是特性(Attribute),这有什么区别?我不想也不会从语义学上去区分,对于这系列文章来说,属性就是组成对象的一个部分,广义上也包括对象的方法,而特性则是指被描述主体所具有的特征,换句话说,属性是我们可以通过编码来访问的具体存在,而特性则主要是为了便于理解概念的抽象存在,当然,特性也可以通过相应的属性来具体外化。这一小节所讲的对象属性的特性就是对对象属性特征的一个描述,主要来自于ECMA-262规范的第5版,该规范使用两个中括号的形式来描述不能直接访问的内部特性。

A、属性类型(先给属性分下类):

数据属性:直接访问属性值的属性 访问器属性:通过getter/setter方法来访问属性值的属性 内部属性:不能通过代码直接访问的属性,只是为了规范说明目的而存在,在规范中也使用两个中括号的形式来描述

B、对象内部属性

  内部属性不能通过代码直接访问,它主要是为了描述规范,也是给ECMAScript实现者参考的,而对于开发者来说,了解这些可以便于理解一些内部机制。比如在给一个属性赋值时,在实现中会调用[[Put]]内部方法,而读取一个属性值时,则调用[[Get]]方法。

所有对象公共的内部属性   个别对象特有的内部属性  
名称   规范   名称   规范   对象  
[[Prototype]]   Object/Null   [[PrimitiveValue]]   primitive   Boolean|Date|Number|String  
[[Class]]   String   [[Construct]]   SpecOp(a List of any) → Object   new  
[[Extensible]]   Boolean   [[Call]]   SpecOp(any, a List of any) → any|Reference   call  
[[Get]]   SpecOp (propName) →any   [[HasInstance]]   SpecOp(any) → Boolean   Function  
[[GetOwnProperty]]   SpecOp (propName) →Undefined|Property Descriptor   [[Scope]]   Lexical Environment   Function  
[[GetProperty]]   SpecOp (propName) →Undefined|Property Descriptor   [[FormalParameters]]   List of Strings   Function  
[[Put]]   SpecOp (propName, any, Boolean)   [

复制代码 代码如下:

]   ECMAScript code   Function  
[[CanPut]]   SpecOp (propName) → Boolean   [[TargetFunction]]   Object   Function.prototype.bind  
[[HasProperty]]   SpecOp (propName) → Boolean   [[BoundThis]]   any   Function.prototype.bind  
[[Delete]]   SpecOp (propName, Boolean) → Boolean   [[BoundArguments]]   List of any   Function.prototype.bind  
[[DefaultValue]]   SpecOp (Hint) → primitive   [[Match]]   SpecOp(String, index) → MatchResult   RegExp  
[[DefineOwnProperty]]   SpecOp (propName, PropDesc, Boolean) → Boolean   [[ParameterMap]]   Object      

说明:

每一个对象都有一个原型对象[[Prototype]],一般我们不能在代码中直接访问这个内部属性,但可以通过Object.getPrototypeOf(object)来获取原型对象(在Firefox中可以通过__proto__来直接访问)。 在Object.prototype.toString方法中,按照规范内建对象会返回包含[[Class]]的值“[object class]”,而内建对象的[[Class]]值就是相应的名称(比如Array对象的[[Class]]值为'Array'),因此可以通过Object.prototype.toString.call(value) == '[object Array]'来判断value是否是一个Array。 给一个属性赋值时,后台调用[[Put]]来实现,获取一个属性值时,后台调用[[Get]]来获取。 使用new操作符调用一个函数时,后台调用[[Construct]],而使用call方法来调用函数时,后台会调用[[Call]][[HasInstance]]方法返回给定参数是否是通过调用函数来创建的,和Object的方法isPrototypeOf(obj)类似。 当一个函数被执行时,就会创建一个[[Scope]]对象,可以理解为[[Scope]]就是我们前面所说的活动对象,也就是说this、arguments、形参、函数内部定义的变量和函数都是的[[Scope]]对象的属性。

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

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