内容要点:

每一个对象都有与之相关的原型(prototype)、类(class)和可扩展性

一.原型属性

1.对象的原型属性是用来继承属性的,这个属性是如此重要,以至于我们经常把 "0的原型属性"直接叫做"o的原型"。

2.原型的属性是在实例对象创建之初就设置好的:通过对象直接量创建的对象使用Object.prototype作为它们的原型。通过new创建的对象使用构造函数的prototype属性作为它们的原型。通过Object.create()创建的对象使用第一个参数(也可以是null)作为它们的原型。

3.在ES5中,将对象作为参数传入Object.getPrototypeOf()可以查询它的原型。在ES3中,则没有与之等价的函数,但经常使用表达式o.constructor.prototype来检测一个对象的原型。

通过new表达式创建的对象,通常继承一个constructor属性,这个属性指代创建这个对象的构造函数。(见9.2类和构造函数)

注意:通过对象直接量或Object.create()创建的对象包含一个名为constructor的属性,这个属性指代Object()函数。因此,constructor.prototype才是对象直接量的真正的原型,但对于通过Object.create()创建的对象则往往不是这样。

4.要想检测一个对象是否是另一个对象的原型(或处于原型链中),使用  isPrototypeOf() 方法。例如:

var p = { x : 1};  //定义一个原型对象

var o = Object.create( p );  //使用这个原型创建一个对象

p.isPrototypeOf(o)             // =>true:o继承p

Object.prototype.isPrototypeOf(o)  //=>true:p继承自Object.prototype

需要注意的是:isPrototypeOf()函数实现的功能和instanceOf运算符非常类似

二.类属性

1.对象的类属性(class attribute)是一个字符串,用以表示对象的类型信息。ES3和ES5都未提供设置这个属性的方法,并只有一种间接的方法可以查询它。默认的toString()方法(继承自Object.prototype)返回了如下这种格式的字符串:

[object,class]

2.classof()函数可以返回传递给它的任意对象的类:

function classof(o){

if(o === null) return "Null";

if(o === undefined) return "undefined";

return Object.prototype.toString.call(o).slice(8,-1);

}

提取已返回字符串的第8个到倒数第二个位置之间的字符。

3.通过内置构造函数(比如Array和Date)创建的对象包含"类属性",它与构造函数名称相匹配。宿主对象也包含有意义的"类属性",但这和具体的JS实现有关。

通过对象直接量和Object.create创建的对象的类属性是"object",那些自定义构造函数创建的对象也是一样,类属性也是"Object",

因此对于自定义的类来说,没办法通过类属性来区分对象的类:

classof(null)  //=>"Null"

classof(1)     //=>"Number"

classof("")   //=>"String"

classof(false) //=>"Boolean"

classof({})   //=> "Object"

classof([])    //=>"Array"

classof(/./)  //=>"Regexp"

classof(new Date())  //=> "Date"

classof(window)  //=>"Window"(这是客户端宿主对象)

function f(){};  //=>定义一个自定义构造函数

classof(new f()) //=>"Object"

三.可扩展性

1.对象的可扩展性用以表示是否可以给对象添加新属性。所有内置对象和自定义对象都是显式可扩展的,宿主对象的可扩展性是由JS引擎定义的。

在ES5中,所有的内置对象和自定义对象都是可扩展的,除非将它们转换为不可扩展的,同样,宿主对象的可扩展性也是由实现ES5的JS引擎定义的

2.ES5定义了用来查询和设置对象可扩展性的函数。通过将对象传入Object.esExtensible(),来判断该对象是否是可扩展的。

如果想将对象转换为不可扩展的,需要调用Object.preventExtensions(),将待转换的对象作为参数传进去。

注意:一旦将对象转换为不可扩展的,就无法再将其转换回可扩展的了。

同样需要注意的是,preventExtensions()只影响到对象本身的可扩展性。如果给一个不可扩展的对象的原型添加属性,这个不可扩展的对象同样会继承这些新属性。

3.可扩展属性的目的是将对象 "锁定",以避免外界的干扰。

对象的可扩展性通常和属性的可配置性与可写性配合使用,ES5定义的一些函数可以更方便地设置多种属性

4.Object.seal()和Object.preventExtensions()类似,除了能够将对象设置为不可扩展的,还可以将对象的所有自有属性都设置为不可配置的。

也就是说,不能给这个对象添加新属性,而且它已有的属性也不能删除或配置,不过它已有的可写属性依然可以设置。

对于那些已经封闭(sealed)起来的对象是不能解封的。可以使用Object.isSealed()来检测对象是否封闭。

Object.freeze()将更严格地锁定对象----"冻结"。除了将对象设置为不可扩展的和将其属性设置为不可配置的之外,还可以将它自有的所有数据属性设置为只读(如果对象的存取器属性具有setter方法,存取器属性将不受影响,仍可以通过给属性赋值调用它们)。使用Object.isFrozen()来检测对象是否冻结。

Object.preventExtensions()、Object.seal()和Object.freeze()都返回传入的对象,也就是说,可以通过函数嵌套的方法调用它们:

//创建一个封闭对象,包括一个冻结的原型和一个不可枚举的属性

var o = Object.seal(Object.create(Object.freeze({x:1})),{y:{value:2,writable:true}});

《JS权威指南学习总结--6.8对象的三个属性》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. Kafka connect快速构建数据ETL通道

    摘要: 作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 业余时间调研了一下Kafka connect的配置和使用,记录一些自己的理解和心得,欢迎 ...

  2. HDU 4403 A very hard Aoshu problem(DFS)

    A very hard Aoshu problem Problem Description Aoshu is very popular among primary school students. I ...

  3. DuiLib 中滚动条不显示的问题

    DuiLib 很好用,同时在没有完全理解源码的前提下,坑也不少,比如今天遇到的添加滚动条不显示... 情况是这样的,将一个页面作为Tab控件的其中一页,为了代码不窝在一起,就没有在CreateCont ...

  4. Oracle odi 数据表导出到文件

    最近新客户要求,以EXCEL数据方式,将数据表的内容,通过AS2协议传输到客户那边,本来打算使用存储过程直接输出EXCEL,但一想,ODI这么强大的工具应该可以直接进行转换,所以参考了一下官方标准文档 ...

  5. 关于angularjs+typeahead的整合

    和angularjs-xeditable的基本相似,主要区别在于前者用于普通input中,后者用于xeditable中 在angularjs-xeditable需要自动提示的地方要用e-uib-typ ...

  6. css 开发心得

    1.一个 div内的行内 元素 如何水平对齐 将内部的元素设为 float  ,然后设置 margin-top 对齐,然后 用伪类清楚浮动的影响

  7. 相机标定 matlab opencv ROS三种方法标定步骤(2)

    二  ubuntu下Opencv的相机标定 一般直接用Opencv的源码就可以进行相机的标定,但是可能只是会实现结果,却不懂实现的过程,我也是模模糊糊的看了<计算机视觉中的多视图几何>以及 ...

  8. C#Winform实现自动更新

    服务端: [WebMethod] public string GetNewService(string version) { //通过版本号进行比较 if (version == "v1.0 ...

  9. 真的了解JS么?

    1.setTimeout setTimeout(function(){ }),1000) setTimeout(function(num){ alert(num)    //弹123 },1000,1 ...

  10. .net程序在无.net环境下运行

    看了篇文章  测试了下竟然真的可以运行  测试环境是XP下  没有装NET2.0的情况下 可以运行的   不过需要每次输入命令才能运行 点击后还是会报错 原文如下 众所周知,.net程序必须运行在.n ...