javascript learning notes——object

《javascript权威指南》这本书有点太专业了,今天只是看了对象和数组。
对象:不知道是我之前看的书太少还是js的对象实在很特别。我感觉js里面的对象和其他语言里面的用法差了很远。
除了字符串、数字、true、false、null和undefined之外,js中的值都是对象
对象是可变的,是通过引用来操作对象的,对象的属性可以变动,甚至还有属性的特性(writable\enumerable\configurable)
对象都拥有的三个相关的对象属性(protoype\class\extensible flag)
三类对象(native obj\host obj\user-defined obj),两类属性(own property\inherited property)

对象最常见的用法是create\set\query\delete\test\enumerate其属性

var o = new Object();//等于{}

每一个js对象(除了null)和都一个prototype关联

new Object(); //Object.prototype
{};//同上
new Date();//Date.prototype
new Array();//Array.prototype

同时Date.prototype和Aray.prototype也是继承于Object.prototype(原型链)

var o = Object.create(null);//o不继承任何属性和方法
var o2 = Object.create(Object.prototype);//和{}、new Object()一样

通过一个原型创建对象:

//inherit()返回一个继承自原型对象p的属性的新对象
//这里使用ECMAScript 5中的Ojbect.create()函数(如果存在的话)
//如果不存在Object.create(),则退化使用其他方法
function inherit(p){
    if (p == null) throw TypeError();//p是一个对象,但是不能为null
    if (Ojbect.create())//如果Object.create()存在,直接使用它
        return Object.create(p);
    var t = typeof p;//否则进行进一步检测
    if (t !== "object" && t!== "function") throw TypeError();
    function f() {};//定义构造函数
    f.prototype = p;//将其原型属性设置为p
    return new f();//使用f()创建p的继承对象
}

继承

var o = {};//o从Object.prototype继承对象的方法
o.x = 1;
var p = inherit(o);//p继承o和Object.prototype
p.y = 2;
var q = inherit(p);//q继承p、o和Object.prototype
q.z = 3;
var s = q.toString();//toString继承自Ojbect.prototype
q.x + q.y //=>3:x和y分别继承自o和p

只有查询属性才会体现得到继承的存在,而设置属性和继承无关

var unitcirle = { r:1 };
var c = inherit(unitcirle);
c.x = 1;
c.y = 1;
c.r = 2;//覆盖
unitcircle.r;//=>1,原对象没有修改

但是,带有getter和setter方法的accessor属性除外,如果对象o继承了属性x(该属性有getter和setter),那么这时将调用setter方法而不是给o创建一个属性x。setter方法由对象o调用,只是操作o本身,不修改原型链:

//对象p表示2D笛卡尔点坐标
var p = {
    //x和y是普通的可读写的数据属性
    x: 1.0,
    y: 1.0,

    //r是可读写的存取器属性,他有getter和setter.
    //函数体结束后不要忘记带上逗号
    get r() {
        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);
    }
};

关于属性访问错误的处理方法:

//返回subtitle的length属性,如果没有则返回undefined
//使用&&的短路行为
var len = book && book.subtitle && book.subtitle.length;

关于删除属性:

//delete只是断开属性和宿主对象的联系,不会去操作属性中的属性
a = {p:{x:1}};
b = a.p;
delete a.p;
b.x//=>1

delete不能删除可配置型为false的属性

this.x = 1;
delete x;//在严格模式下回报错
delete this.x;

使用in\hasOwnProperty\propertyIsEnumerable来检测对象属性

属性的特性包括value\writable\enumerable\configurable,使用defineProperty设置

var o = {};//创建一个空对象
//添加一个不可枚举的数据属性x,并赋值为1
Object.defineProperty(o, "x", {value: 1,
                                writable: true,
                                enumerable: false,
                                configurable: true});

对象的三个属性:prototype\class\extensible attribute

标签:javascript, object, array