javascript object
javascript对象都是关联数组
关联数组:数组是通过字符串索引的而不是数字索引。(也称:散列,映射,字典)
创建javascript对象的几种方法
对象直接量
例子:
var empty = {} //空对象,用大括号包含
var point = {x:0, y:2} //对象的属性如上,多个属性用逗号隔开
var point2 = {x:point.x, y:point.y} //对象调用属性的值用.加上属性名来获得。
var book = {
“main title”: “javascript”,
“sub-tittle”:”The Definitive Guide”,
“for”:”all audiences”,
author:{
name:”danny”,
sex:”male”
}
}
//属性名有空格需要用引号引起来
//属性名有连字符要用引号引起来
//属性名时javascript的关键字用引号引起来
//属性时一个对象
通过new关键字创建对象
var obj = new Object(); //创建一个空的对象
var arr = new Array(); //创建一个空数组
var date = new Date(); //创建一个表示当前时间的Date对象,Date是javascript内置函数
var reg = new RegExp(“js”); //创建一个进行模式匹配的RegExp对象
除了内置构造函数,用户自定义构造函数用来初始化对象也是非常常见的
原型
1.javascript的大多数对象都是从原型继承属性的。
2.可以通过Object.prototype获得对原型对象的引用。
Object.create()创建对象
ECMAScript 5定义了一个名为Object.create()的方法,它创建一个对象。其中第一个参数是这个对象的原型,第二个可选参数用以对对象的属性进行描述。
列子:
var obj = Object.create({x:1, y:3});
//obj 继承了属性x 和 y
var obj2 = Object.create(null);
//创建一个没有原型的新对象,但是通过这种方法创建的对象不会继承任何东西,甚至不包括基础的方法,比如toString(),它不能和“+”运算符一起工作
var obj3 = Object.create(Object.prototype);
//这个创建和{} , new Object()相同
ECMAScript 3中可以通过类似的方法实现原型继承
例子:
function inherit(p) {
if (p == null) throw TypeError(); //p是一个对象但是不能为null
if (Object.create) {
return Object.create(p);
//如果Object.create()方法存在直接使用
}
var t = typeof p;
//进一步检测
if (t !== “Object” && t !== “function”) {
throw TypeError();
} else {
function f() {}; //定义一个空构造函数
f.prototype = P;//将其原型属性设置为p
return new f();
}
}
对象属性的操作
获得对象的属性值的方法
从对象中获取属性的值有两种方式
例如;
var book = {
“main title”: “javascript”,
“sub-tittle”:”The Definitive Guide”,
“for”:”all audiences”,
author:{
name:”danny”,
sex:”male”
}
}
//当属性没有引号的时候
var author = book.author;
//当属性有引号的时候,当然没有引号的以可以使用此方法,反过来不可以
var title = book[“main title”];
//对象还可以取到原型的属性值和方法
删除属性
//delete只能删除自有属性不能输出继承属性
delete book.author;
delete book[“title”];
//delete不能删除那些可配置性为false的属性,某些内置对象的属性时不可配置的,比如通过变量申明和函数申明创建的全局对象的属性。
delete Object.prototype;//不能删除,属性时不可配置的
var x = 1;
delete this.x;//不能删除全局变量
fucntion f() {};
delete this.f;//不能删除全局函数
检测属性
javascript对象可以看做是属性的集合,我们进场会检测集合中的成员的所属关系–判断某个属性是否存在于某个对象中。可以通过in运算符,hasOwnProperty()和propertyIsEnumerable()方法来完成这个工作,甚至仅通过属性查询就可以做到这一点。
例子:
var obj = {x:1}
“x” in obj; //true: “x”是obj的属性
“y” in obj; //false: “y”不是obj的属性
“toString” in obj;//true: o继承toString属性
使用hasOwnProperty()
hasOwnProperty()只检测自有的属性
obj.hasOwnProperty(“x”);//true
obj.hasOwnProperty(“y”);//false
obj.hasOwnProperty(“toString”);//false
//propertyIsEnumerable()是hasOwnProperty()的增强版,只有检测到是自有属性并且这个属性的可枚举性为true它才返回true
var obj = inderit({y: 2});
obj.x = 2;
obj.propertyIsEnumerable(“x”); //true
obj.propertyIsEnumerable(“y”); //false
Object.prototype.propertyIsEnumerable(“toString”);//false
另一种更加简单的方法时使用”!==”来判断一个属性是否时undefined
var obj = {x:3, z: undefined}
obj.x !== undefined; //true
obj.y !== undefined; //false
obj.toString !== undefined; //true
“z” in obj; //true,这种情况不能使用undefined来做判断
属性除了包含键值对之外,属性还有一些标示它们可写(writable)、可枚举(enumerable)和可配置(configurable)的特性。
ECMAScript 3中没有这样的属性特性的区分,在ECMAScript 5中才对这些特性进行了约束。
ECMAScript 5提供了查询和设置这些属性特性的API。
API功能:
1.可以给原型对象添加方法,并将它们设置成为不可枚举的,这让它们看起来更像内置方法。
2.可以给对象定义不能修改或者删除的属性,借此“锁定”这个对象。
为了实现属性特性的查询和设置操作,ECMAScript 5中定义了一个名为“属性描述符”(property descriptior)对象
var obj = {
x: 1,
y: 3,
get r() {
return Math.sqrt(this.x*this.x + this.y*this.y);
},
set r(value) {
var oldvalue = Math.sqrt(this.x*this.x + this.y*this.y);
var ratio = value/oldvalue;
this.x *= ratio;
this.y *= ratio;
},
get theta() {
return Math.atan2(this.y, this.x);
}
}
Object.getOwnPropertyDescriptor(obj,”x”);
结果:
Object {value: 1, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor()方法只能得到自有属性的描述符,想要获得继承属性的描述符,则需要便利原型连
Object.getPrototypeOf(obj);
设置属性的特性
这是修改单个属性的特性的方法
Object.defineProperty(obj,”x”,{ writable: false, enumerable: false, configurable: false});
这是同时修改多个属性特性的方法
Object.defineProperties(obj,{
z:{ writable: true, enumerable: false, configurable: false},
y:{writable: false, enumerable: false, configurable: false}});
注意
1.如果对象时不可扩展的,则可以编辑以有的自有属性,但是不恩能够添加新属性。
2.如果属性时不可配置的,则本鞥修改它的可配置性和可枚举性。
3.如果存取器属性时不可配置的,则不能修改setter和getter方法,也不能将它转化为数据属性。
4.如果属性是不可配置的,则不能将它转换为存取器属性。
5.如果属性时不可配置的,则不能将它的可写性从false修改未true,但是可以从true修改为false。
6.如果属性时不可配置并且不可写的,则不能修改它的值。然而可配置但不可写的属性的值时可以修改的(实际上是先将属性标记为可写的,然后修改它的值,最后转换为不可写的)