内容要点:

每一个对象都有与之相关的原型(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. 【转】深入理解javascript原型和闭包(完结)

    直接传送门-------------------->>>>>>>> 深入理解javascript原型和闭包(完结)

  2. bootstrp-select插件使用

    需要导入 <link rel="stylesheet" href="js/plugins/silviomoreto-bootstrap-select20151109 ...

  3. USACO 3.4 Raucous Rockers

    Raucous Rockers You just inherited the rights to N (1 <= N <= 20) previously unreleased songs ...

  4. C#:继承多态的方法实现数的简单加减乘除运算

       // 定义一个抽象的父类     abstract class Figure     {         //声明抽象方法:         //父类中的所有家里人可以用的方法必须都应用到子类中 ...

  5. MATLAB的符号运算基础

    在数学运算中,运算的结果如果是一个数值,可以称这类运算为数值运算:如果运算结果为表达式,在MATLAB中称为符号运算,符号计算是对未赋值的符号对象(可以是常数.变量.表达式)进行运算和处理.MATLA ...

  6. 问题记录2:TypeError: write() argument must be str, not bytes

    今天试了下用requests模块的get()方法来下载图片,写入文件的时候不能写入二进制,然后将打开方式改成二进制的就好了. 原因是,f.content的存储方式是二进制,而文件正常打开默认是字符串的 ...

  7. vedio_note_1

    同步复位 always @ (posedge clk) ....... 异步复位 always @ (posedge clk or negedge rst_n) ....... 异步复位和同步复位的优 ...

  8. AFURLRequestSerialization

    NSString * AFPercentEscapedStringFromString(NSString *string)   //去除非法字符并且对特殊字符进行编码.  //对字符串进行百分比编码 ...

  9. mysql的联合,连接,子查询

  10. PXE+kickstart自动安装ubuntu14.04

    本文参考了诸多文章,先感谢这些文章的作者. 使用pxe安装系统需要安装dhcp,tftp,http等服务(当然也可以使用其他文件共享方式比如nfs,ftp). 实验环境: 1. vmware 12 2 ...