JavaScript中的Object对象学习教程


Posted in Javascript onMay 20, 2016

参数:
(1)obj
必需。Object 对象分配到的变量名称。 
(2)值
可选。任一 JavaScript 基元数据类型(数字、布尔值或字符串)。  如果值是一个对象,则返回的对象是未修改的。  如果值是 null、“未定义”或“未提供”,则创建无内容的对象。 

Object对象的方法

Object作为构造函数使用时,可以接受一个参数。如果该参数是一个对象,则直接返回这个对象;如果是一个原始类型的值,则返回该值对应的包装对象。利用这一点,可以写一个判断变量是否为对象的函数。

function isObject(value) {
 return value === Object(value);
}

要在Object对象上面部署一个方法,有两种做法。

部署在Object对象本身
部署在Object.prototype对象
Object.keys方法和Object.getOwnPropertyNames方法很相似,一般用来遍历对象的属性。它们的参数都是一个对象,都返回一个数组,该数组的成员都是对象自身的(而不是继承的)所有属性名。两者区别在于,前者只返回可枚举的属性,后者还返回不可枚举的属性名。由于数组存在不可枚举属性length,因此一般使用Object.keys遍历数组。

JavaScript没有提供计算对象属性个数的方法,可通过 Object.keys(o).length 和 Object.getOwnPropertyNames(o).length 获取。

Object.observe方法用于观察对象属性的变化。

原型链相关方法:

Object.create():生成一个新对象,并该对象的原型。
Object.getPrototypeOf():获取对象的Prototype对象。
Object实例对象的方法

Object.prototype.valueOf():valueOf方法的作用是返回一个对象的值,默认情况下返回对象本身。该方法的主要用途是,JavaScript自动类型转换时会默认调用这个方法。

Object.prototype.toString():toString方法的作用是返回一个对象的字符串形式。当对象用于字符串加法时,会自动调用toString方法。

使用call方法,可以在任意值上调用Object.prototype.toString方法,从而判断这个值的类型。不同数据类型的toString方法返回值如下:

数值:返回[object Number]
字符串:返回[object String]
布尔值:返回[object Boolean]
undefined:返回[object Undefined]
null:返回[object Null]
对象:返回”[object “ + 构造函数的名称 + “]”

Object.prototype.toString.call(2) // "[object Number]"
Object.prototype.toString.call('') // "[object String]"

利用这个特性,可写出一个比typeof运算符更准确的类型判断函数。

var type = function (o){
 var s = Object.prototype.toString.call(o);
 return s.match(/\[object (.*?)\]/)[1].toLowerCase();
};

type({}); // "object"
type([]); // "array"
type(5); // "number"

在上面这个type函数的基础上,还可以加上专门判断某种类型数据的方法。

['Null', 'Undefined', 'Object', 'Array', 'String', 'Number',
'Boolean', 'Function', 'RegExp', 'Element', 'NaN', 'Infinite'
].forEach(function (t) {
 type['is' + t] = function (o) {
  return type(o) === t.toLowerCase();
 };
});

type.isObject({}); // true
type.isNumber(NaN); // false
type.isElement(document.createElement('div')); // true

对象的属性模型

在JavaScript内部,每个属性都有一个对应的attributes对象,保存该属性的一些元信息。使用Object.getOwnPropertyDescriptor方法,可读取o对象的p属性的attributes对象。attributes对象包含如下元信息:

value:表示该属性的值,默认为undefined(只要writable和configurable有一个为true,就可以改动)。
writable:表示该属性的值(value)是否可以改变,默认为true。
enumerable: 表示该属性是否可枚举,默认为true,也就是该属性会出现在for…in和Object.keys()等操作中。一般来说,系统原生的属性(即非用户自定义的属性)都是不可枚举的。
表示“可配置性”,默认为true。如果设为false,表示无法删除该属性,也不得改变attributes对象(value属性除外,如果writable为true,仍可改变value),也就是configurable属性控制了attributes对象的可写性。
表示该属性的取值函数(getter),默认为undefined。
表示该属性的存值函数(setter),默认为undefined。

var o = { p: 'a' };
Object.getOwnPropertyDescriptor(o, 'p');
// Object {
//  value: "a",
//  writable: true,
//  enumerable: true,
//  configurable: true
// }

Object.defineProperty方法允许通过定义attributes对象,来定义或修改一个属性,然后返回修改后的对象。格式如下:

Object.defineProperty(object, propertyName, attributesObject)
Object.defineProperty方法接受三个参数,第一个是属性所在的对象,第二个是属性名(它应该是一个字符串),第三个是属性的描述对象。通过此方法定义属性,属性对象的writable、configurable、enumerable三个属性的默认值都为false。

Object.defineProperty(o, "p", {
 value: "bar"
});
Object.getOwnPropertyDescriptor(o, 'p');
// Object {
//  value: "bar",
//  writable: false,
//  enumerable: false,
//  configurable: false
// }

如果一次性定义或修改多个属性,可以使用Object.defineProperties方法。需要注意的是,一旦定义了取值函数get(或存值函数set),就不能将writable设为true,或者同时定义value属性,否则会报错。

var o = Object.defineProperties({}, {
 p1: {value: 123, enumerable: true},
 p2: {value: "abc", enumerable: true},
 p3: {
  get: function () {
   return this.p1 + this.p2
  },
  enumerable: true,
  configurable: true
 }
});

enumerable可以用来设置“秘密”属性,如果一个属性的enumerable为false,则 for..in 循环、Object.keys 方法和 JSON.stringify 方法都不会取到该属性,但可以通过 o.xx 直接获取它的值。

for…in循环和Object.keys方法的区别在于,前者包括对象继承自原型对象的属性,而后者只包括对象本身的属性。如果需要获取对象自身的所有属性,不管enumerable的值,可以使用Object.getOwnPropertyNames方法。

可配置性决定了一个变量是否可以被删除(delete)。当使用var命令声明变量时,变量的configurable为false,而不使用var命令声明变量时(或者使用属性赋值的方式声明变量),变量的可配置性为true。这说明,delete只能删除对象的属性。

var a1 = 1; // configurable: false
a2 = 1; // configurable: true(等价于this.a2 = 1)

除了直接定义以外,属性还可以用存取函数(accessor)定义。其中,存值函数称为setter,使用set命令;取值函数称为getter,使用get命令。利用存取函数,可以实现数据对象与DOM对象的双向绑定。

Object.defineProperty(user, 'name', {
 get: function () {
  return document.getElementById("foo").value
 },
 set: function (newValue) {
  document.getElementById("foo").value = newValue;
 },
 configurable: true
});

控制对象状态

JavaScript提供了三种方法,精确控制一个对象的读写状态,防止对象被改变。最弱一层的保护是preventExtensions,其次是seal,最强的freeze。

Object.preventExtensions方法可以使得一个对象无法再添加新的属性,但可以用delete命令删除它的现有属性。Object.isExtensible方法可以用来检查是否可以为一个对象添加属性。

Object.seal方法使得一个对象既无法添加新属性,也无法删除旧属性。Object.seal还把现有属性的attributes对象的configurable属性设为false,使得attributes对象不再能改变。Object.isSealed方法用于检查一个对象是否使用了Object.seal方法。

Object.freeze方法可以使得一个对象无法添加新属性、无法删除旧属性、也无法改变属性的值,使得这个对象实际上变成了常量。Object.isFrozen方法用于检查一个对象是否使用了Object.freeze()方法。

使用上面这些方法锁定对象的可写性,但是依然可以通过改变该对象的原型对象,来为它增加属性。

var o = new Object();
Object.preventExtensions(o);
var proto = Object.getPrototypeOf(o);
proto.t = "hello";
o.t
// hello

一种解决方案是,把原型也冻结住。

var o = Object.seal(
 Object.create(Object.freeze({x:1}),
   {y: {value: 2, writable: true}})
);
Object.getPrototypeOf(o).t = "hello";
o.t // undefined

PS:
Object 对象包含在所有其他 JavaScript 对象中;它的所有方法和属性均可用于所有其他对象。  方法可在用户定义的对象中进行重新定义,并由 JavaScript 在适当时间调用。   toString方法是频繁重新定义的 Object 方法的一个示例。 
在此语言参考中,每个 Object 方法的说明均包括内部 JavaScript 对象的默认和对象特定的实现信息。
IE兼容方面,微软MSDN文档的话是”已在 Internet Explorer 6 之前的 Internet Explorer 中引入 Object Object“,所以不用担心~

Javascript 相关文章推荐
JQquery的一些使用心得分享
Aug 01 Javascript
jquery 插件开发 extjs中的extend用法小结
Jan 04 Javascript
使用GruntJS构建Web程序之Tasks(任务)篇
Jun 06 Javascript
JavaScript eval() 函数介绍及应用示例
Jul 29 Javascript
jQuery操作表单常用控件方法小结
Mar 23 Javascript
Angularjs在360兼容模式下取数据缓存问题的解决办法
Jun 22 Javascript
Angular2 组件间通过@Input @Output通讯示例
Aug 24 Javascript
JavaScript实现的超简单计算器功能示例
Dec 23 Javascript
如何将你的AngularJS1.x应用迁移至React的方法
Feb 01 Javascript
vue.js 2.*项目环境搭建、运行、打包发布的详细步骤
May 01 Javascript
浅谈Express.js解析Post数据类型的正确姿势
May 30 Javascript
node 标准输入流和输出流代码实例
Sep 19 Javascript
jQuery基本选择器(实例及表单域value的获取方法)
May 20 #Javascript
jQuery的实例及必知重要的jQuery选择器详解
May 20 #Javascript
深入理解setTimeout函数和setInterval函数
May 20 #Javascript
JavaScript基础教程——入门必看篇
May 20 #Javascript
jQuery选择器及jquery案例详解(必看)
May 20 #Javascript
Jquery $when done then的用法详解
May 20 #Javascript
jQuery添加和删除输入文本框标签代码
May 20 #Javascript
You might like
PHP 数组入门教程小结
2009/05/20 PHP
PHP SPL标准库中的常用函数介绍
2015/05/11 PHP
详解WordPress中用于更新和获取用户选项数据的PHP函数
2016/03/08 PHP
Yii操作数据库实现动态获取表名的方法
2016/03/29 PHP
Laravel 5.4向IoC容器中添加自定义类的方法示例
2017/08/15 PHP
NiftyCube——轻松实现圆角边框
2007/02/20 Javascript
js和php如何获取当前url的内容
2013/09/22 Javascript
JQuery中使用Ajax赋值给全局变量失败异常的解决方法
2014/08/18 Javascript
JavaScript编程中的Promise使用大全
2015/07/28 Javascript
jQuery中hover与mouseover和mouseout的区别分析
2015/12/24 Javascript
jQuery实现下拉框左右移动(全部移动,已选移动)
2016/04/15 Javascript
一览画面点击复选框后获取多个id值的方法
2016/05/30 Javascript
js获取html的span标签的值方法(超简单)
2016/07/26 Javascript
JavaScript定义数组的三种方法(new Array(),new Array('x','y')
2016/10/04 Javascript
简单实现Bootstrap标签页
2020/08/09 Javascript
javascript基础知识讲解
2017/01/11 Javascript
详解基于angular-cli配置代理解决跨域请求问题
2017/07/05 Javascript
js 事件的传播机制(实例讲解)
2017/07/20 Javascript
JS分页的实现(同步与异步)
2017/09/16 Javascript
解决vue无法设置滚动位置的问题
2018/10/07 Javascript
js核心基础之构造函数constructor用法实例分析
2019/05/11 Javascript
完美解决vue 中多个echarts图表自适应的问题
2020/07/19 Javascript
详解Vue.js 可拖放文本框组件的使用
2021/03/03 Vue.js
编写Python CGI脚本的教程
2015/06/29 Python
Linux 修改Python命令的方法示例
2018/12/03 Python
Python pandas.DataFrame 找出有空值的行
2019/09/09 Python
Python基于Socket实现简易多人聊天室的示例代码
2020/11/29 Python
python实现双人五子棋(终端版)
2020/12/30 Python
ALEX AND ANI:手镯,项链,耳环和更多
2017/04/20 全球购物
大学生作弊检讨书
2014/02/19 职场文书
病危通知单
2015/04/17 职场文书
毕业晚宴祝酒词
2015/08/11 职场文书
竞聘开场白方式有哪些?
2019/08/28 职场文书
Pytorch distributed 多卡并行载入模型操作
2021/06/05 Python
台积电称即便经济低迷也没有降价的计划
2022/04/21 数码科技
javascript中Set、Map、WeakSet、WeakMap区别
2022/12/24 Javascript