《javascript语言精粹》学习笔记 - 对象

Javascirpt里的对象是无类型的。它对新属性的名字和属性的值没有任何的限制。对象适用于聚集和管理数据。对象能够包括其余对象,因此它们能够容易地表示成树状或者图形结构。数组

对象字面量

建立一个自定义对象最简单的方式就是建立一个Object的实例,而后为它添加属性和方法:闭包

var person = new Object();
    person.name = 'john';
    person.age = 16;
    person.say = function(){
        console.log(this.name + ' ' + this.age);
    };

后来对象字面量成为一个建立这种对象的首选方式。对象字面量提供一种很是方便的建立新对象的表示法。函数

var Person = {},
    Person2 = {
        name: 'john',
        age: 16,
        say: function(){
            console.log(this.name + ' ' + this.age);
        }
    };

一个对象字面量就是包围在一对花括号({})的多个名/值对。对象字面量能够出现任何容许表达式出现的地方。ui

属性名能够包括空字符串在内的任何字符。属性名是一个合法的js标示符并且不是保留字的话就不用引号括起来。特殊状况例如:"my-name"这种的话,由于js中的标示符中包含链接符(-)是不合法的,因此要用引号去包住,若是用下划线(_)就不用了。this

对象字面量属性值里面能够在嵌套对象的。prototype

var Person = {
    name: 'john',
    Person2: {
        age: 16
    }
};

检索

要检索的对象包含的值,能够采用[]后缀中括住一个字符串表达式方式。也能够用.方法,可是前提要是一个合法的js标示符且不是保留字。code

person['name'];
person.name;

若是属性值没有的话,咱们能够用||充当默认值。对象

var name = person['name'] || 'john';

尝试从undefind对象里取值将会致使TypEerror异常。能够经过&&运算符来避免错误。继承

flight.equipment // undefined
flight.equipment.model // TypeError
flight.equipment && flight.equipment.model// undefined

引用

对象是经过引用来传递的,而不是复制。ip

// 例子一
var stooge = {},
    x = stooge;
x.nickname = 'john';
var nick = stooge.nickname;
alert(nick); // john

// 例子二
var a = {}, b = {}, c = {};
// a = b = c = {};
  • 例子一的代码由于xstooge是指向同一个对象的引用。
  • 例子二的代码其实abc都引用同一个对象。

更新

对象可使用赋值语句来更新值。若是属性名已经存在的话,就回去被替换掉。若是值不存在,就扩充到对象中。

var person = {
    name: 'Ada'
}
person.name = 'john'; // john
person.age = 16 // 16

原型

每一个对象都能链接到一个原型对象,而且它能够从中继承属性。

当你建立一个新的对象的时候,你能够有选择性的某个对象做为它的原型。js给咱们的机制是很复杂的,可是能够被明显的简化,来给Object添加一个create方法。

if (typeof Object.beget !== 'function') {
    Object.create = function(o){
        var F = function(){};
        F.prototype = o;
        return new F;
    };
}
var person = Object.create(person);

注意:原型链接在更新时是不会起做用的。当对某个对象作出改变的时候,不会触及该对象的原型。

原型连接只有在检索值的时候才会用到。若是咱们尝试去获取对象的某个值的时候,若是对象没有该属性名,那么js会尝试去原型对象中获取属性值。若是那个原型也没有的话,就会一直从它的原型里面找。若是最后仍是找不到的话机会返回一个undfined。这个过程称为委托

原型关系是一种动态的关系。若是添加到一个新的属性值到原型中,该属性会当即对全部基于这个原型建立的对象可见。

反射

检查对象而且肯定对象有什么属性是一件很容易的事情,只要尝试的去检索那个属性而且验证取得的值。使用typeof来对肯定属性的类型。

var person = {
    name: 'john',
    age: 16,
    say: function(){
        console.log(this.name + ' - ' + this.age);
    }
};
alert(typeof person.name); // string
alert(typeof person.age); // number
alert(typeof person.say); // function

另一种方法是使用hasOwnProperty方法,若是对象拥有独有的属性值,它将会放回true。注意:hasOwnProperty方法不会检查原型链。

alert(person.hasOwnProperty('name')); // true
alert(person.hasOwnProperty('sex')); // false

枚举

for in循环能够用来遍历一个对象中的说有属性名。
注意:使用for in循环过程当中也会列出那些你不关心的原型中的属性,若是想要过滤掉那些你不须要的值。你可使用hasOwnProperty方法,以及typeof来排除函数。

for (var name in person) {
    if (typeof person[name] !== 'function') {
        alert(person[name]);
    }
};

属性名出现的顺序是不肯定的,所以要对全部的可能出现的顺序有所准备。若是想要确保属性以特定的顺序出现,最好的办法就是彻底避免使用for in语句,而是建立一个数组,在其中以正确的顺序包含属性名。

var i = 0,
    properties = [
        'name',
        'age'
    ];
for (; i < properties.length; i++) {
    alert(person[properties[i]]);
};

经过使用for循环而不是for in循环,就能够获得想要的值,也不用担忧可能发掘出原型链中的属性。

删除

delete运算符能够用来删除对象的属性。若是对象包含这个属性,那么该属性就会被移除。亦不会触及原型链中的任何对象。

var Person = function(name, age){
    this.name = name;
    this.age = age;
};
Person.prototype.name = 'Ada';

var person = new Person('john', 16);

alert(person.name); // john
delete person.name;
alert(person.name); // Ada

删除对象的属性可能会让来自原型链中的属性透现出来。

严格模式下,不能用delete 删除显式声明的标识符,名称或具名函数。

减小全局变量污染

js能够很随意去定义全局变量来容纳你的应用的全部的资源。很差的是,全局变量削弱了程序的灵活性,应该都要避免使用。

最小化使用全局变量的方法之一就是为你的应用只建立一个惟一的全局变量。

var MyApp = {};

这个变量就会成为你的应用的容器了。

MyApp.person = {
    name: 'john',
    age: 16
};

MyApp.person2 = {
    name: 'Age',
    age: 14,
    sayName: function(){
        alert('name: ' + this.name);
    }
};

只要把全局性的资源都归入一个名称空间下,本身写的程序与其余的程序、组件或者类库之间发生的冲突就会大大的减小。本身写的程序也会变得更加容易的阅读。还有另一种方法也是能够有效的减小全局污染,那就是闭包

相关文章
相关标签/搜索