在我看来常规性程式设计是操作方式统计数据,所以元程式设计是操作方式标识符。对 JavaScript 此种静态词汇,二者之间没严苛的界线。生活习惯静态词汇的开发人员即使会真的单纯的 for/in 循环式插值第一类优点也有“元”的香味。元程式设计在日常生活合作开发中不常用,主要就用作库合作开发,也常被那些想所制 JS 第一类犯罪行为技术细节的合作开发人员高度关注。
他们晓得,JS 的第一类是优点的子集。第一类和优点这类也都具备许多优点。那些优点客观存有著,但又不为常规性 API 所牵涉,故把它归为元程式设计。德圣茹,第一类的优点囊括三个各方面:1. 能增设第一类的优点与否能减少,即扩展性。2. 第一类常常和另三个第一类有著关连,他们叫它蓝本第一类。优点的优点主要就包括优点与否展毛、可隐式、可实用性。
优点的优点
优点的优点负面影响优点的犯罪行为,和你能对优点展开的操作方式。假如他们把值优点的值,读取器优点的 get, set 方式也看做是优点的优点,就能说,值优点的优点有:值这类、与否展毛、与否可隐式、与否可实用性。读取器优点的优点有:与否存有 getter 方式、与否存有 setter 方式、与否可隐式、与否可实用性。读取器优点透过 getter,setter 方式的存有性抒发与否可随机存取。
优点的优点采用优点实用性文件来则表示,优点实用性文件是三个第一类。对值优点,优点实用性文件形如:
对读取器优点,优点实用性文件形如:
第一类字面值中定义的优点、透过赋值操作方式添加的优点默认是展毛、可隐式、可实用性的。但 JS 标准库定义的优点很多都不是这样。一般地,他们希望蓝本第一类上定义的方式是不可隐式的,也是不希望在 for/in 循环式中插值出蓝本上的方式。JS 提供了 API 来查询、增设优点的优点,既能在优点新增时顺便增设优点,也能修改已有优点的优点。优点实用性文件不一定要包含全部的四个优点。新增优点时,未设定的优点默认为 false 或 undefined。修改已有优点时,未指定的优点不受负面影响。对优点优点的查询和增设都只牵涉自身优点,不会牵涉蓝本第一类上的优点。
Object.getOwnPropertyDescriptor()
接收三个参数,分别是第一类,优点名。返回优点实用性文件。对不存有的优点和继承自蓝本的优点返回 undefined。
Object.defineProperty()
接收三个参数,分别是第一类、优点名、优点实用性文件。该方式修改并返回第三个参数第一类。用作新增或修改优点,抒发式名中的 define 可能让人有种只能新增的错觉,其实修改操作方式也可看做 redefine,重定义。
Object.defineProperties()
接收三个参数,分别是第一类、优点名到优点实用性文件的映射第一类。该方式修改并返回第三个参数第一类。第二个参数第一类也能传为 Object.create() 的第二个参数。
这样一来,新增或修改优点就有了两种方式,常规性方式是采用第一类字面值和优点赋值,麻烦但强大的是采用 Object.defineProperty() 等,能称此种为实用性的方式。受优点类型和优点的负面影响,对属性的修改并不总能成功,即使是采用实用性的方式。读取器优点除了在第一类字面值中定义,就只能采用实用性的方式定义或修改了。所以,假如三个读取器优点是不可实用性的,所以你就无法对它做任何人改动。可能令人意外的是,不可写的优点,优点值未必不能改变:与否展毛控制的是与否可赋值,但假如不展毛的优点是可实用性的,所以仍然能采用实用性的方式改变其值。最后,可实用性性还决定优点与否可删除,不可实用性的优点无法被 delete。
第一类的扩展性
第一类的扩展性说的是优点与否可减少。不可扩展的第一类,你能修改它的现有优点值,但无法减少优点,也不可更换它的蓝本。普通 JS 第一类默认都是可扩展的,能采用 Object.preventExtensions() 让第一类不可扩展,能采用 Object.isExtensible() 得知第一类与否可扩展。注意,蓝本第一类不受负面影响,且由于继承的静态性,给蓝本减少优点,依然能被不可扩展的第一类继承到。第一类的扩展性常和优点的优点联合增设,遂有以下方式打包增设:
Object.seal()
让第一类不可扩展,且让自身优点不可实用性。判断方式:Object.isSealed()。
Object.freeze()
在 Object.seal() 的基础上让自身值优点只读。判断方式:Object.isFrozen()。
那些方式都不会负面影响蓝本第一类,且都修改并返回其操作方式的第一类。
第一类的蓝本
第一类常常有三个蓝本第一类与之关连
Object.getPrototypeOf()
Object.setPrototypeOf()
修改第一类的蓝本。
o1.isPrototypeOf(o2)
判断第一类 o1 与否是 o2 的蓝本(o1 与否在 o2 的蓝本链上,不一定要是蓝本链的头结点),和 instanceof 机制类似。
在许多早期的浏览器实现中,第一类实例上还具备 __proto__ 优点,让第一类直接和蓝本打交道,是可随机存取的。