Javascript语言精粹对象读书笔记

193 阅读3分钟

对象

  • Javascript中的简单类型:number,string,boolean,null,undefined。
  • 其他所有值都是对象。 对象是属性的容器,每个属性都有名字和值。属性的名字可以是任意字符串(包含空字符串),属性值可以是除undefined外的任意值。对象无类别。

对象字面量

创建新对象值 { 名/值 } 属性值可获得

var empty_object = {}; //创建空对象
var stooge = {
    "first-name":"Joe",
    "last-name":"Howard"
}

对象可嵌套

//嵌套对象的创建
var flight = {
    airline:"Oceanic",
    number:815,
    departure:{ //嵌套对象
        IATA:"SYD",
        time:"2004-09-22 14:55",
        city:"Sydney"
    },
    arrival:{
        IATA:"LAX",
        time:"2004-09-23 10:42",
        city:"Los Angeles"
    }
}

检索

  • 对象[属性名]
stooge["first-name"]  //"Joe"
flight.departure.IATA  //"STD"
  • 检索不存在的属性名的值,将返回undefined
stooge["middle-name"]  //undefined
flight.status  //undefined
  • 使用 || 填充默认值
var middle = stooge["middle-name"] || "(none)";
var status = flight.status || "unknown";
  • 使用 && 避免TypeError
flight.equipment  //undefined
flight.equipment.model //throw "TypeError"
flight.equipment && flight.equipment.model  //undefined

更新

属性名已存在于对象中,原属性值会被替换

stooge['first-name'] = 'Jerome';

属性名不存在,该属性被扩充到该对象中

stooge['middle-name'] = 'Lester';
stooge.nickname = 'Curly';
flight.equipment = {
    model:'Boeing 777'
};
flight.status = 'overdue';

引用

对象通过引用来传递而非拷贝

var x = stooge;
x.nickname = 'Curly';
var nick = stooge.nickname;
    // x和stooge是指向同一个对象的引用 -> nick = 'Curly'

var a = {}, b = {}, c = {};
    // a, b, c指向的是不同的空对象
a = b = c = {};
    //a, b, c引用的是同一个空对象

原型

  • 每个对象都连接到一个原型对象,且可以从中继承属性。
  • Object.prototype是javascript中标准的对象,所有通过对象字面量创建的对象都连接到Object.prototype
  • 给Object添加一个beget方法,创建一个使用原对象作为其原型的新对象
if(typeof Object.beget !== 'function'){
    Object.beget = function(o) {
        var F = function(){};
        F.prototype = o;
        return new F();
    };
}
var another_stooge = Object.beget(stooge);
  • 对新对象的更新不会影响原型
another_stooge['first-name'] = 'Harry';
another_stooge['middle-name'] = 'Moses';
another_stooge.nickname = 'Moe';
  • 原型关系是一种动态关系。在原型中添加新属性,新属性会立即对所有基于该原型创建的对象可见
stooge.profession = 'actor';
another_stooge.profession  //'actor'

原型连接只有在检索值时才会被用到。如果我们尝试获取对象的某个属性值,但该对象没有此属性名,那么javascript会尝试从原型对象中获取该属性值。如果这个原型对象也没有该属性,那么再从它的原型中寻找,以此类推,直至该过程到达终点Object.prototype。如果该属性不存在于原型链中,结果将是undefined值。这个过程称为委托

反射

利用typeof操作符确定属性的类型

typeof flight.number  //'number'
typeof flight.arrival   //'object'

//原型链中的任何属性也会产生一个值
typeof flight.toString //'function'

如何处理这些不需要的属性

  1. 让程序检查并剔除函数值
  2. 使用hasOwnProperty方法,该方法不会检查原型链
//对象拥有独有的属性时返回true
flight.hasOwnProperty('number')  //true
flight.hasOwnProperty('constructor')  //false

枚举

使用 for in 语句枚举一个对象中的所有属性名,属性名出现的顺序是不确定的。使用 for 可以按照正确的顺序取到他们的值。

// for in
var name;
for (name in another_stooge) {
    if (typeof another_stooge[name] != 'function') {
        document.writeln(name + ':' + another_stooge[name]);
    }
}
// for
var i;
var properties = {  //存储another_stooge中存在的属性名
    'first-name',
    'middle-name',
    'last-name',
    'profession'
};
for (i = 0; i < properties.length; i += 1) {
    document.writeln(properties[i] + ':' + another_stooge[properties[i]] );
}

删除

delet可以删除对象的属性,但会在索引时读取到来自原型链中的属性

another_stooge.nickname  //'Moe'
delete another_stooge.nickname  //删除操作
another_stooge.nickname  //'Curly' 索引到原型链中的属性值

减少全局变量污染

全局变量削弱了程序的灵活性,所以应该避免。
我们可以通过创建唯一一个全局变量var MYAPP = {}来最小化使用全局变量

MYAPP.stooge = {
    "first-name":"Joe",
    "last-name":"Howard"
}

通过把多个全局变量整理在一个名称空间下,我们可以降低与其他应用程序、组件或类库之间产生的相互影响的可能性。