JavaScript对象

1、创建对象

可以通过对象直接量,关键字new,object.create()三种方法来创建对象

 

对象直接量

 

var empty = {};   //没有任何属性的对象
var point = {x:0,y:0};  //两个属性
var point2 = {x:point.x,y:point.y}  //更复杂的值
var book = {
    'main title':'javascript',  //属性名字里面有空格,必须用字符串表示
    sub-title':'The Definitive Guide',  //属性名字里面有连字符,必须用字符串表示
    'for':'all audiences',  //'for'是保留字,必须用引号
    author:{  //这个属性的值是一个对象
            firstname:'David',  //注意,这里的属性名都没有引号
        surname:'Flanagan'
    }
}        

 

 

通过new创建对象

new运算符创建并初始化一个对象,关键字后面跟一个函数调用,这个函数称作构造函数,构造函数用于初始化一个新创建的对象

 

var o = new Object();  //创建一个空对象,和{}一样
var a = new Array();  //创建一个空数组,和[]一样
var d = new Date();  //创建一个表示当前时间的Date对象
var r = new RegExp('js');  //创建一个可以进行模式匹配的RegExp对象

 

 

原型

每个对象都会从原型对象继承属性

通过对象直接量创建的对象,会继承自原型Object.prototype

通过new Object(),继承自原型Object.prototype

通过new Date(),继承原型Date.prototype.

通过new Array(),继承原型Array.prototype.

通过new RegExp,继承原型RegExp.prototype

Date.prototype,Array.prototype,RegExp.prototype继承自原型Object.prototype

Object.prototype是唯一一个没有原型的对象

 

object.create()

object.create()创建了一个新对象,第一个参数是这个对象的原型,提供第二个可选参数,可以对对象的属性进行进一步的描述

object.create() 是一个静态函数,而不是提供给某个对象调用的方法。使用方法简单,只需传入所需的原型对象即可

 

var o1 = Object.create({x:1,y:1});  //o1继承了属性x和y
var o2 = Object.create(null);  //不继承任何属性和方法
var o3 = Object.create(Object.prototype);  //o3和{}和new Object()一样,属于一个普通的空对象

 

 

 

2、属性的查询和设置

通过 . []用来获取和设置属性,点运算符是静态的,写死的,不能改变。[]是动态的,在运行是可进行修改。

var book = {
        'main title':'javascript',
        'sub-title':'The Definitive Guide',
        'for':'all audiences',
        author:{
            firstname:'David',
            surname:'Flanagan'
        }
}

var author = book.author;  //得到book的'author'属性
var name = author.surname;  //Flanagan
var title = book['main title']; //javascript
book.edition = 6;  //给book创建了一个名为'edition'的属性
book['main title'] = 'ECMAScript';  //给'main title'属性赋值

 

继承

对象具体有自有属性,也有一些属性是从原型对象继承而来。

假设要查询对象o的属性x,如果o中不存在x,那么将会在o的原型对象中继续查找属性x。如果原型对象中也没有x,但这个原型对象也原型,那么继续这个原型对象的原型上继续查找,直到找到x或者查到到一个原型是null的对象为止。

只有在查找时才会体会到继续的存在,设置和赋值和继承无关

 

var o = {};  //o从Objec.prototype 继承对象的方法
o.x = 1;  //给o定义一个属性x
var p = inherit(o);  //p继承o和Objec.prototype
var p.y = 2;  //给p定义一个属性y
var q = inherit(p);  //q继承p、o、Object.prototype
q.z = 3;  //给q定义一个属性z
var s = q.toString();  //toString继承自Object.prototype
q.x+q.y  //3:x和y分别继承自o和p

 

var unitcircle = {r:1};  //一个用来继承的对象
var c = inherit(unitcircle);  //c继承属性r
c.x = 1;c.y = 1;  //c定义两个属性
c.r = 2;  //c覆盖继承来的属性
unitcircle.r;  //1:原型对象没有修改

 

 

3、删除属性

delete运算符可以删除对象属性,只能删除自有属性,不能删除继承属性

 

var book = {
        'main title':'javascript',
        'sub-title':'The Definitive Guide',
        'for':'all audiences',
        author:{
                firstname:'David',
                surname:'Flanagan'
        }
 }
delete book.author;  //book不再有属性author
delete book['main title']  //book不再有属性'main title'

 

当delete表达式删除成功或者没有任何副作用的时候,返回true

var o = {x:1};  //o有一个属性x,并继承属性toString
delete o.x;  //删除x,返回true
delete o.x;  //什么都没做(x已经不存在),返回true
delete o.toString();  //什么都没做(toString是继承来的),返回true
delete 1;  //无意义,返回true

 

 

4、属性检测

四种方法:in运算符,hasOwnPreperty(),propertyIsEnumberable(),属性查询

 

in运算符

 

var o = {x:1};
'x' in o;  //true:x是o的属性
'y' in o;  //false:y不是o的属性
'toString' in o;  //true:o继承toString属性

 

hasOwnProperty()方法用来检测给定的名字是否是对象的自由属性。对于继承属性将返回false

var o = {x:1};
o.hasOwnProperty('x');  //true:o有一个自有属性x
o.hasOwnProperty('y');  //false:o不存在属性y
o.hasOwnProperty('toString');  //false:toSting 是继承属性

propertyIsEnumerable()是hasOwnProperty()的增强版,只有检测到是自有属性且这个属性的可枚举性为true时才返回true

var o = inherit({y:2});
o.x = 1;
o.propertyIsEnumerable('x');  //true:o有一个可枚举的只有属性x
o.propertyIsEnumerable('y');  //false:y是继承来的
o.propertyIsEnumerable('toString');  //false:不可枚举

通过'!=='进行判断

var o = {x:1};
o.x !== undefined;  //true:o中有属性x
o.y !== undefined;  //false:o中没有属性y
o.toString() !== undefined;  //true:o继承了toString属性

 

 

5、枚举属性

 

for/in循环可以在循环体内遍历对象中所有可枚举的属性(包括自有和继承的属性);对象继承的内置方法不可枚举,在代码中给对象添加的属性都是可枚举的

var o = {x:1,y:2,z:3};
o.propertyIsEnumerable('toString');  //false:不可枚举
for(var p in o){
      console.log(p);  //输出x、y、z
}

for(var p in o){
        if(!o.hasOwnProperty(p)) continue;  //跳过继承的属性
}

 

 

6、对象属性 -- getter和setter

如果属性同时具有getter和setter方法,那么它是一个读/写属性;如果只有getter方法,那么它是一个只读属性;如果只有setter方法,那么它是一个只写属性。存取器属性可以继承

var o = {
        data_prop:value,  //普通的数据属性
        get accessor_prop(){...},  //存取器属性
        set accessor_prop(value){...}
}
var p = {
               x:1.0,
               y:1.0,
               get r(){ return Math.sqrt(this.x*this.x+this.y+this.y);},
               set r(newvalue){
                   var oldvalue = Math.sqrt(this.x*this.x+this.y+this.y);
                   var ratio = newvalue/oldvalue;
                   this.x *=ratio;
                   this.y *=ratio;
               },
               get theta(){ return Math.atan2(this.y,this.x);}
       }
       console.log(p.r);
       console.log(p.theta);

 

7、对象属性的特性

除了包含名字和值之外,属性还包含一些标识他们可写、可枚举和可配置的的特性

一个属性包含一个名字和4个特性。
数据属性特性:值(value)、可写性(writable)、可枚举行(enumerable)、可配置性(configurable)
存取器属性:取(get)、写入(set)、可枚举行(enumerable)、可配置性(configurable)

 

Object.getOwnPropertyDescriptor() 可以获得某个对象特定属性的“属性描述符”(4个特性),只能得到自有属性的描述符

var o = {x:1,y:2};
console.log(Object.getOwnPropertyDescriptor(o,'x'));  //Object {value: 1, writable: true, enumerable: true, configurable: true}
var p = {
           x:1.0,
           y:1.0,
           get r(){ return Math.sqrt(this.x*this.x+this.y+this.y);},
           set r(newvalue){
               var oldvalue = Math.sqrt(this.x*this.x+this.y+this.y);
               var ratio = newvalue/oldvalue;
               this.x *=ratio;
               this.y *=ratio;
           },
           get theta(){ return Math.atan2(this.y,this.x);}
}
console.log(Object.getOwnPropertyDescriptor(p,'r'));  //configurable:true enumerable:true get:r() set:r(newvalue)

对于继承属性和不存在的属性,返回undefined

console.log(Object.getOwnPropertyDescriptor({},'x'))  //undefined
console.log(Object.getOwnPropertyDescriptor({},'toString'))  //undefined

 Object.defineProperty()--设置属性的特性,或者想让新建属性具体有某种特性,只能设置自有属性,不能修改继承属性

var o = {};
Object.defineProperty(o,'x',{
    value:1,
    writable:true,
    enumerable:false,
    configurable:true
})
console.log(o.x);  //1
console.log(Object.getOwnPropertyDescriptor(o, 'x'));  //Object {value: 1, writable: true, enumerable: false, configurable: true}

Object.defineProperties -- 同时修改或者创建多个属性

Object.defineProperties({},{
    x{value:1,writable:true,enumerable:true,configurable:true},
    y{value:1,writable:true,enumerable:true,configurable:true},
    r:{
            get:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},
            enumerable:true,
            configurable:true
    }
})

 

 

8、对象的三个属性 -- 原型(prototype)、类(class)、可扩展性(extensible attribute)

isPrototypeOf() -- 检测一个对象是否是另一个对象的原型

 

var p = {x:1};
var o = Object.create(p);
console.log(p.isPrototypeOf(o));  //true:o继承自p
console.log(Object.prototype.isPrototypeOf(o));  //true:p继承自Object.prototype

 

 

可扩展性

 

对象的可扩展性用以表示是否可以给对象添加新属性。默认所有内置对象和自定义对象都是可扩展的。
Object.isExtensible() -- 判断对象是否可扩展
Object.preventExtensions() -- 将对象转换为不可扩展的,一旦将对象转换为不可扩展的,就无法将其转换回可扩展的了,只影响对象本身的可扩展性,如果给一个不可扩展的对象的原型添加属性,这个不可扩展的对象同样会继承这些新属性
Object.seal() -- 将对象设置为不可扩展,并将对象的所有自有属性都设置为不可配置的。已经封闭的对象不能解封
Object.isSealed() -- 检测对象是否已封闭(sealed)
Object.freeze() -- 将对象设置为不可扩展,并将对象的所有自有属性都设置为不可配置的和只读
Object.isFrozen() -- 检测对象是否冻结(frozen)

var o = {x:1};
console.log(Object.isExtensible(o));  //true
Object.preventExtensions(o);
console.log(Object.isExtensible(o));  //false
Object.seal(o);
console.log(Object.getOwnPropertyDescriptor(o,'x'));  //{value: 1, writable: true, enumerable: true, configurable: false}
console.log(Object.isSealed(o));  //true
Object.freeze(o);
console.log(Object.getOwnPropertyDescriptor(o,'x'));  //{value: 1, writable: false, enumerable: true, configurable: false}
console.log(Object.isFrozen(o));  //true

 

 

9、序列化对象

 

对象序列化(serialization)是指将对象的状态转换为字符串,也可将字符串还原为对象
JSON.stringify() -- 将对象的状态转换为字符串
JSON.parse() -- 将字符串还原为对象

var o = {x:1,y:{z:[false,null,'']}};
s = JSON.stringify(o);
console.log(s);  //{"x":1,"y":{"z":[false,null,""]}}
console.log(typeof s)  //string
p = JSON.parse(s);
console.log(p);  //object {x:1,y:{z:[false,null,'']}};
console.log(typeof p)  //object

 

posted @ 2017-07-08 17:23  影子疯  阅读(157)  评论(0编辑  收藏  举报