Object是在javascript中一个被我们经常使用的类型,而且JS中的所有对象都是继承自Object对象的。虽说我们平时只是简单地使用了Object对象来存储数据,并没有使用到太多其他功能,但是Object对象其实包含了很多很有用的属性和方法,尤其是ES5增加的方法,因此,本文将从最基本的介绍开始,详细说明Object的常用方法和应用。
对象初始化
首先我们都知道,对象就是一组相似数据和功能的集合,我们就是用它来模拟我们现实世界中的对象的。那在Javascript中,创建对象通常有两种方式:对象字面量和构造函数。
对象字面量
对象字面量是以"{ }"作为边界,以多个键值对组成。
var obj = {name:"terry",age:12,gender:"male"}
构造函数
可以使用Object系统内置的对象构造函数,也可以使用自定义构造函数。
var obj = new Object();//var obj = {};
obj 是对象,也被称为实例。object 是类,也被称为构造函数,是创建函数的模板。
属性访问【读、写】
点访问(对象.属性)var obj = {name:"terry"}obj.name; //'terry'//赋值var obj = {};obj.name = 'terry';
JS允许随时新增属性,不一定要在定义对象的时候,就定义好属性。(在java对象中,定义对象时就确定了属性不可更改)。
中括号访问(对象[变量])
var obj = {name:"terry"}obj["name"];//'terry'var name1 = "name";obj[name1];//'terry'
注意:中括号访问时,键名必须放在引号里面,否则会被当作变量处理。
属性遍历(for-in)
var obj = {name:"terry",age:12,gender:"male"}for(var key in obj){console.log(key,obj[key]);}
依次从obj中获取属性名赋值给key,通过obj[key]访问属性值。
属性删除(delete)
delete命令用于删除对象的属性,代码格式为:delete 对象 . 属性,删除成功后返回true。
var obj = {name:"terry"};delete obj.name // trueobj.name // undefined
注意:如果删除的是一个不存在的属性,返回值是true。只有当该属性存在且不可删除时,delete命令才会返回false。
对象序列化
对象序列化是将内存中的对象转化成字符串的描述,解决对象在io流中传输的问题。
在网络中传输时,只允许传输字符或者字节流。具体的有两种交互方式:json字符串和qs查询字符串。
var obj = {name:"terry",age:12,gender:"male"}
常规转换
obj.toString()//'[object Object]'
转换为json字符串
JSON.stringify(obj) // {"name":"terry","age":12,"gender":"male"}
转换为查询字符串
var qs = require('querystring');qs.stringify(obj);//name=terry&age=12&gender=male
Object 对象
Object是所有构造函数的父(根)构造函数,所有的构造函数都直接间接的继承Object。所有的实例对象都可以调用其构造函数及其父构造函数的原型中的方法。
Object()可以作为构造函数,新生成一个对象var obj = new Object();
,也可以作为工具函数,将任意值转为对象var obj = Object(参数);
。
如果参数是基本类型,那么Object()方法会将其转换成对应构造函数的实例。
var obj = Object(1); //var obj = Number(1);obj instanceof Object // trueobj instanceof Number // true
instanceof 运算符用来验证一个对象是否为指定的构造函数的实例。
如果参数本来就是一个对象,那么它就不会再做任何转换直接返回该对象。利用这一点,可以写一个判断变量是否为对象的函数。
function isObject(value) {return value === Object(value);};isObject(function(){}) // trueisObject(true)// false
Object 静态方法
Object 静态方法是Object本身的方法,也就是直接定义在Object对象的方法。静态方法只能Object构造函数本身调用,它的实例对象是不能调用的。下面为大家介绍几个常用的静态方法。
Object.defineProperty()
这个方法可以在一个对象上定义一个新属性,或者修改一个已经存在的属性。存在很高的自定义性,灵活运用可满足我们很多实际需求。属于Object对象的高级知识。语法:Object.defineProperty(obj, prop, descriptor);
,其中obj为要定义或修改属性的对象,prop为要定义或修改的属性名称,descriptor为要定义或修改的属性的描述符。
var obj = {};obj.name = "terry";//name可迭代,可读可写//等价于:Object.defineProperties(obj,{name:{},})Object.defineProperty(obj,"name",{//共享的可选键值对configurable:true, //是否可修改/删除(默认为false)enumerable:true, //是否可枚举(默认为false)//数据描述符键值对writable:true,//是否可写(默认为false)value:"terry" ,//属性值//存取描述符键值对//set:function(){ },//get:function(){ }});
数据描述符键值对和存取描述符键值对都可以搭配共享的可选键值对组成完整的数据描述符或者存取描述符。但是数据描述符键值对和存取描述符键值对不能同时出现在一个描述符里的,否则会报错。
如果我们想实时监测对象新增属性的值发生的变化,可以对存取描述符键值对(get / set)进行设置。
var obj = {_age:12};Object.defineProperty(obj,"age",{configurable:false, enumerable:true, set:function(day){console.log("生日快乐"); this._age = day;},get:function(){return this._age;},});obj.age++; // 第一次生日obj.age++; // 第二次生日obj.age++; // 第三次生日console.log(obj.age);console.log(obj);//生日快乐//生日快乐//生日快乐//15//{_age:15,age:[Getter/Setter]}
需要注意的是,下滑线开头的属性一般定义的是内置属性,是不允许轻易访问的,通常会对外暴露一个同名无下划线的属性age,_age属性其实是age属性的真正存储位置。从结果来看,外部每次修改age的值,我们都监测到了。
Object.keys()、 Object.getOwnPropertyNames()
这两种方法都是用来遍历对象的属性的,接受一个对象作为参数,返回一个数组,包含了该对象自身的所有属性名。
var obj = {name:"terry",age:12,gender:"male"};Object.keys(obj); // ['name','age','gender']Object.getOwnPropertyNames(obj); // ['name','age','gender']
需要注意的是,Object.keys()方法只遍历可枚举属性;Object.getOwnPropertyNames()方法还遍历不可枚举的属性名。以数组对象为例:
var arr = ["terry",12,"male"];Object.keys(arr); // ['0','1','2']Object.getOwnPropertyNames(arr); // ['0','1','2','length']
Object 的静态方法有很多,现在先给大家罗列一下,就不一一介绍了,等项目中需要使用的时候再详细说明吧~
对象属性模型的相关方法:
Object.getOwnPropertyDescriptor():获取某个属性的描述对象。Object.defineProperty():通过描述对象,定义某个属性。Object.defineProperties():通过描述对象,定义多个属性。
控制对象状态的方法:
Object.preventExtensions():防止对象扩展。Object.isExtensible():判断对象是否可扩展。Object.seal():禁止对象配置。Object.isSealed():判断对象是否可配置。Object.freeze():冻结对象。Object.isFrozen():判断对象是否被冻结。
原型链相关方法:
Object.create():指定原型对象和属性,返回一个新的对象。Object.getPrototypeOf():获取对象的Prototype对象。
Object 实例方法
由于JavaScript 的所有其他对象都继承自Object对象(即其他对象都是Object的实例),所以它们都可以调用Object的实例方法。Object.prototype的实例方法有很多,下面先给大家介绍几个最常用的。
Object.prototype.constructor
返回对象的构造函数。
var obj = {};console.log(obj.constructor); // [function:Object]
Object.prototype.valueOf()
返回当前对象对应的值,默认情况下返回对象本身。
var obj = {name:"terry",gender:"male"};console.log(obj.valueOf()); // {name:"terry",gender:"male"}obj.valueOf() === obj // true
Object.prototype.toString()
将对象转换成字符串的描述,默认转换成[object,Object]的形式。
var obj = new Object();console.log(obj.toString()); // [object,Object]
由于所有的构造函数都直接或间接的继承Object,因此所有的数据类型都可以调用toString()方法。JS都系统自定义了toString方法:
(123).toString() // "123"'123'.toString() // "123"[1,2,3].toString() // "1,2,3"(function () {return 123;}).toString()// "function () {// return 123;// }"
Object.prototype.hasOwnProperty()
判断属性值是否属于当前实例。
var obj = {name:"terry" };console.log(obj.hasOwnProperty("name")); // trueconsole.log(obj.hasOwnProperty("toString")); // false//toString是继承来的,并不属于当前实例
Object.prototype.propertyIsEnumerable()
判断属性是否可枚举(遍历)。
var obj = {name:"terry" };console.log(obj.propertyIsEnumerable("name")); // trueconsole.log(obj.propertyIsEnumerable("toString")); // false