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 相关文章推荐
xml分页+ajax请求数据源+dom取结果实例代码
Oct 31 Javascript
javascript中的float运算精度实例分析
Aug 21 Javascript
requireJS使用指南
Apr 27 Javascript
微信小程序开发教程-手势解锁实例
Jan 06 Javascript
jquery代码规范让代码越来越好看
Feb 03 Javascript
jQuery层级选择器_动力节点节点Java学院整理
Jul 04 jQuery
JavaScript实现单例模式实例分享
Dec 22 Javascript
JS实现基于拖拽改变物体大小的方法
Jan 23 Javascript
jQuery实现网页拼图游戏
Apr 22 jQuery
vue强制刷新组件的方法示例
Feb 28 Javascript
vscode配置vue下的es6规范自动格式化详解
Mar 20 Javascript
微信小程序基础教程之echart的使用
Jun 01 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
NO3第三帝国留言簿制作过程
2006/10/09 PHP
Ajax PHP分页演示
2007/01/02 PHP
php.ini 配置文件的深入解析
2013/06/17 PHP
PHP查询网站的PR值
2013/10/30 PHP
ThinkPHP之foreach标签使用概述
2014/06/30 PHP
PHP超低内存遍历目录文件和读取超大文件的方法
2019/05/01 PHP
PHP7创建销毁session的实例方法
2020/02/03 PHP
Jquery颜色选择器ColorPicker实现代码
2012/11/14 Javascript
js关闭浏览器窗口及检查浏览器关闭事件
2013/09/03 Javascript
node.js中的fs.openSync方法使用说明
2014/12/17 Javascript
javascript实现随时变化着的背景颜色
2015/04/02 Javascript
js实现同一页面多个不同运动效果的方法
2015/04/10 Javascript
JS实现DIV容器赋值的方法
2015/12/14 Javascript
JS常用字符串方法(推荐)
2021/01/15 Javascript
React根据宽度自适应高度的示例代码
2017/10/11 Javascript
浅谈开发eslint规则
2018/10/01 Javascript
如何使用 vue + d3 画一棵树
2018/12/03 Javascript
JS闭包原理与应用经典示例
2018/12/20 Javascript
Python中datetime常用时间处理方法
2015/06/15 Python
菜鸟使用python实现正则检测密码合法性
2016/01/05 Python
Python实现删除时保留特定文件夹和文件的示例
2018/04/27 Python
Python实现基于KNN算法的笔迹识别功能详解
2018/07/09 Python
python3.5基于TCP实现文件传输
2020/03/20 Python
Python2与Python3关于字符串编码处理的差别总结
2020/09/07 Python
matplotlib 三维图表绘制方法简介
2020/09/20 Python
PyTorch 中的傅里叶卷积实现示例
2020/12/11 Python
美国精油公司:Plant Therapy
2019/05/17 全球购物
NULL是什么,它是怎么定义的
2015/05/09 面试题
托管代码(Managed Code)和非托管代码(Unmanaged Code)有什么区别
2014/09/29 面试题
班主任工作经验交流材料
2014/05/13 职场文书
美术专业自荐信
2014/07/07 职场文书
反四风个人对照检查材料思想汇报
2014/09/25 职场文书
财政局党的群众路线教育实践活动剖析材料
2014/10/13 职场文书
保护校园环境倡议书
2015/04/28 职场文书
2016年大学生社区服务活动总结
2016/04/06 职场文书
SQL Server数据库备份和恢复数据库的全过程
2022/06/14 SQL Server