在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. 烂泥:apache性能测试工具ab的应用

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. 网站性能压力测试是服务器网站性能调优过程中必不可缺少的一环.只有让服务器处在高压情况下,才能真正体现出软件.硬件等各种设置不当所暴露出的问题. 性能测试 ...

  2. linux 分区 物理卷 逻辑卷

    今天我们主要说说分区.格式化.SWAP.LVM.软件RAID的创建哈~ 格式化 查看当前分区:fdisk   -l 这个命令我们以前是讲过的,我现在问下,ID那项是什么意思? 83 是代表EXT2和E ...

  3. android Timer使用方法

    Timer属性:http://www.apihome.cn/api/java/Timer.html 声明创建: private Timer mTimer; protected void onCreat ...

  4. 错误“Unexpected namespace prefix "xmlns" found for tag LinearLayout”的解决方法(转)

    (转自:http://blog.csdn.net/bombzhang/article/details/12676789) 有一次升级开发工具后发现xml脚本出现错误“Unexpected namesp ...

  5. JAVA 基本运算符(摘)

    (搞自:Java经典入门教程) http://wenku.baidu.com/link?url=IoWI58cD5vzeHN-NL4pN7Gren-RfzydrhjDlETAByC9L-9ANinyL ...

  6. 注意Android里TextView控件的一个小坑,用android:theme来设置样式时动态载入的layout会丢失该样式

    注意Android里TextView控件的一个小坑,用android:theme来设置样式时动态载入的layout会丢失该样式 这个坑,必须要注意呀, 比如在用ListView的时候,如果在List_ ...

  7. 报表引擎API开发入门— EJB程序数据源

    我们前面讲了几个数据源,今天我们来讲一下EJB数据源,这篇讲完我们数据源这部分就讲完了.数据连接不需要直接访问数据库,而是使用EJB做为数据源.FR通过定义程序数据集使用EJB的相关类获取到EJB数据 ...

  8. 【温故而知新-Javascript】使用 Ajax(续)

    1. 准备向服务器发送数据 Ajax 最常见的一大用途是向服务器发送数据.最典型的情况是从 客户端发送表单数据,即用户在form元素所含的各个 input 元素里输入的值.下面代码展示了一张简单的表单 ...

  9. Java开发之Servlet之间的跳转

    一.转向(Forward) 1.要点说明 转向是通过RequestDispatcher对象的forward()方法来实现的.RequestDispatcher可以通过HttpServletReques ...

  10. Luogu题目集合[6/未完待续]

    1. P1327数列排序 题目描述 给定一个数列{an},这个数列满足ai≠aj(i≠j),现在要求你把这个数列从小到大排序,每次允许你交换其中任意一对数,请问最少需要几次交换? 输入输出格式 输入格 ...