在JavaScript中对象是一个无序属性的集合,其属性可以包含基本值、对象或者函数。

对象最简单的创建方式

JavaScript中创建对象最简单的方式就是创建一个Object对象的实例,然后再添加属性和方法。

var person = new Object();

person.name = 'jenemy';
person.age = 24; person.getName = function() {
return this.name;
}

另一种写法是使用对象字面量语法,这种方式看起来更加简洁,而且更加通用。

var person = {
name: 'jenemy',
age: 24,
getName: function() {
return this.name;
}
}

然后可以通过person.name或者person['name']获取对象的属性。

通过Object构造函数和对象字面量的创建的对象有以下特点

  • 可以任意修改其属性和方法
  • 可以通过delete删除其属性和方法

对象的属性类型

ESMAScript中有两种属性:数据属性和访问器属性

数据属性

数据属性包含一个值,例如前面的person对象name属性。数据属性有4个描述其行为的特性:

  • [[Configurable]]:默认值为true,表示能否通过 delete 删除属性从而重新定义属性、能否修改属性的特性,或者能否把属性修改为访问器属性。
  • [[Enumerable]]: 默认值为true,表示是否通过for-in循环返回属性。
  • [[Writable]]:默认值为undefined,表示是否能修改属性的值。
  • [[Value]]:默认值undefined,包含这个属性的数据值。

要修改默认的属性值,必须使用ECMAScript5的Object.defineProperty()方法,这个方法接收三个参数:属性所在的对象、属性的名字和一个描述符对象。其中属性描述符必须是:configurable、enumerable、writable和value。

var person = {};
person.age = 25;
Object.defineProperty(person, 'name', {
configurable: false,
enumerable: false,
value: 'jenemy'
}); person.name; // jenemy
person.name = 'xiaolu'; // name属性不可修改
person.name; // jenemy
delete person.name; // name属性不可以删除
person.name; // jenemy // name属性不可以使用for..in返回属性
for(var p in person) {
console.log(p); // age
}
// 同样也不能使用Object.keys()返回
Object.keys(person); // ["age"] // 一旦使用definedProperty()定义属性后就不可以再更改了
// Uncaught TypeError: Cannot redefine property: name
Object.defineProperty(person, 'name', {
configurable: true,
});

如果需要同时设定多个属性值,可以使用Object.defineProperties()方法。

var person = {};
Object.defineProperties(person, {
name: {
value: 'jenemy'
},
age: {
value: 25
}
});

访问器属性

访问器属性不包含数据值,它包含一对儿getter和setter函数。在读取访问器时,会调用getter函数,这个函数会返回有效的值。在写入访问器属性时,会调用setter函数并传入新值。访问器属性有4个特性:

  • [[Configurable]]:默认值为true,表示能否通过 delete 删除属性从而重新定义属性、能否修改属性的特性,或者能否把属性修改为访问器属性。
  • [[Enumerable]]: 默认值为true,表示是否通过for-in循环返回属性。
  • [[Get]]:默认值为undefined,在读取属性时调用的函数。
  • [[Set]]:默认值为undefined,在写入属性时调用的函数。

访问器属性同样需要defineProperty()来定义

var person = {
_name: 'jenemy',
};
Object.defineProperty(person, 'name', {
get: function() {
return this._name
},
set: function(newValue) {
this._name = '我的新名字:' + newValue;
}
}); person.name; // jenemy
person.name = 'xioalu';
person.name; // 我的新名字:xioalu

获取属性的特性

使用ECMAScript中的Object.getOwnPropertyDescriptor()方法,可以取得指定属性的描述符。

var person = {
name: 'jenemy',
age: 25
} // {value: "jenemy", writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(person, 'name');

禁止修改对象

对象和属性都有指导其内部属性行为的内部特征。其中,[[Extensible]]是一个布尔值,它指明该对象本身是否可以被修改。默认情况下,对象本身是可以被扩展的。

设置[[Extensible]]为false,就可以禁止新属性的添加。有3中方式来实现对对象的锁定。

禁止扩展

第一种方式是使用Object.preventExtensions()创建一个不可扩展的对象。可以使用Object.isExtensible()来检查[[Extensible]]的值。

var person = {
name: 'jenemy'
} Object.isExtensible(person); // true Object.preventExtensions(person);
person.addr = 'shanghai';
person.addr; // undefined
Object.isExtensible(person); // false person.age = 23;
person.age; // 23
delete person.age;
person.age; // undefined

可以看出,虽然我们不能添加新的属性,但是可以修改和删除已有的属性。

对象封印

使用Object.seal()可以来封印一个对象。该方法被调用时,[[Extensible]]特征被设置为false,其所有属性的[[Configurable]]特征被转为false;可以使用Object.isSealed()判断一个对象是否被封印。

var person = {
name: 'jenemy'
}
Object.seal(person);
Object.isSealed(person); // true person.addr = 'shanghai';
person.addr; // undefined person.age = 23;
person.age; // 23 // {value: "jenemy", writable: true, enumerable: true, configurable: false}
Object.getOwnPropertyDescriptor(person, 'name'); delete person.name; // false

可以看到我们依然可以修改已有对象的属性,但是对象被封印后其属性就不能使用delete操作符删除了。

对象冻结

使用Object.freeze()可以冻结一个对象,被冻结的对象将不能再添加或者删除属性,不能改变属性类型,也不能写入任何数据属性。同样有一个对应的Object.isFrozen()来判断一个对象是否被冻结。

var person = {
name: 'jenemy'
}
Object.freeze(person);
Object.isFrozen(person); // true person.addr = 'shanghai';
person.addr; // undefined person.age = 23;
person.age; // 24, 不可以修改 // {value: "jenemy", writable: false, enumerable: true, configurable: false}
Object.getOwnPropertyDescriptor(person, 'name'); delete person.name; // false

现在这个对象完全不可以添加、删除、更改属性了。

参考

-《JavaScript高级程序设计》(第3版)

-《JavaScript面向对象精要》

-《Effective JavaScript》

js基础知识温习:js中的对象的更多相关文章

  1. js基础知识温习:Javascript中如何模拟私有方法

    本文涉及的主题虽然很基础,在很多人眼里属于小伎俩,但在JavaScript基础知识中属于一个综合性的话题.这里会涉及到对象属性的封装.原型.构造函数.闭包以及立即执行表达式等知识. 公有方法 公有方法 ...

  2. Js基础知识7-JavaScript所有内置对象属性和方法汇总

    对象什么的,程序员可是有很多呢... JS三大对象 对象,是任何一个开发者都无法绕开和逃避的话题,她似乎有些深不可测,但如此伟大和巧妙的存在,一定值得你去摸索.发现.征服. 我们都知道,JavaScr ...

  3. js基础知识温习:构造函数与原型

    构造函数 构造函数主要用于初始化新对象.按照惯例,构造函数名第一个字母都要大写. 构造函数有别于其它函数在于它使用new操作符来调用生成一个实例对象.换句话说,如果一个函数使用new操作符来调用,则将 ...

  4. Node.js基础知识

    Node.js入门   Node.js     Node.js是一套用来编写高性能网络服务器的JavaScript工具包,一系列的变化由此开始.比较独特的是,Node.js会假设在POSIX环境下运行 ...

  5. [JS复习] JS 基础知识

    项目结尾,空闲时间,又把<JS 基础知识> 这本书过了一遍,温故知新后,很多知其然不知其所以然的内容 豁然开朗. [1. 用于范围的标签] display  :inline or bloc ...

  6. NodeJs>------->>第三章:Node.js基础知识

    第三章:Node.js基础知识 一:Node.js中的控制台 1:console.log.console.info  方法 console.log(" node app1.js 1> ...

  7. JS基础知识笔记

    2020-04-15 JS基础知识笔记 // new Boolean()传入的值与if判断一样 var test=new Boolean(); console.log(test); // false ...

  8. 网站开发进阶(十五)JS基础知识充电站

    JS基础知识充电站 1.javascript alert弹出对话框时确定和取消两个按钮返回值? 用的不是alert对话框,是confirm confirm(str); 参数str:你要说的话或问题: ...

  9. HTML+CSS+JS基础知识

    HTML+CSS+JS基础知识 目录 对HTML+CSS+JS的理解 基础知识 对HTML+CSS+JS的理解 基础知识 插入样式表的三种方式 外部样式表:<link rel="sty ...

随机推荐

  1. CPU卡与M1卡的区别

    简单来讲CPU卡比M1卡更加安全.扩展性更好.支持更多应用   CPU卡 M1 操作系统 带有COS系统 无COS系统 硬件加密模块 硬件DES运算模块 无实现算法的硬件加密模块 算法支持 标准DES ...

  2. .NET领域驱动设计—实践(穿过迷雾走向光明)

    阅读目录 开篇介绍 1.1示例介绍 (OnlineExamination在线考试系统介绍) 1.2分析.建模 (对真实业务进行分析.模型化) 1.2.1 用例分析 (提取系统的所有功能需求) 1.3系 ...

  3. Python基本语法,python入门到精通[二]

    在上一篇博客Windows搭建python开发环境,python入门到精通[一]我们已经在自己的windows电脑上搭建好了python的开发环境,这篇博客呢我就开始学习一下Python的基本语法.现 ...

  4. python简单爬虫定时推送同花顺直播及荐股至邮箱

    1.初衷:实践 2.技术:python requests Template 3.思路:根据直播页面获取评价最高的前十博主,定时爬行最新的消息和实战股票 4.思路:python 编辑简单邮件html模板 ...

  5. mongoDB删除表中一个字段

    使用update命令 update命令 update命令格式: db.collection.update(criteria,objNew,upsert,multi) 参数说明: criteria:查询 ...

  6. 绕过校园网的共享限制 win10搭建VPN服务器实现--从入门到放弃

    一.开篇立论= =.. 上次说到博主在电脑上搭建了代理服务器来绕过天翼客户端的共享限制,然而经过实际测试还不够完美,所以本着生命不息,折腾不止的精神,我又开始研究搭建vpn服务器= =... (上次的 ...

  7. glibc-2.15编译error: linker with -z relro support required

    ./configure --prefix=/usr/local/glibc-2.15 configure: error: you must configure in a separate build ...

  8. Linux下Redis开机自启(Centos)

    废话少说,直接来步骤: 1.设置redis.conf中daemonize为yes,确保守护进程开启. 2.编写开机自启动脚本 vi /etc/init.d/redis 脚本内容如下: # chkcon ...

  9. Redhat下如何搭建NFS

    环境: OS:Red Hat Linux As 5 服务器ip:192.168.50.199客户端ip:192.168.50.200 1.服务器上创建共享目录同时修改权限mkdir /bak1/nfs ...

  10. 准备使用 Office 365 中国版--购买

    Office 365中国版支持两种购买方式,Web Direct(在线购买)和CSP(代理商购买).如果客户的企业规模不大(几十个用户,小于100用户)或者是个人/家庭购买,可以直接选择在线购买方式. ...