资讯专栏INFORMATION COLUMN

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

LoftySoul / 758人阅读

摘要:对象适用于汇集和管理数据。一个对象字面量就是包围在一对花括号的多个名值对。尝试从对象里取值将会导致异常。亦不会触及原型链中的任何对象。严格模式下,不能用删除显式声明的标识符,名称或具名函数。

  

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);
        }
    };

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

属性名可以包括空字符串在内的任何字符。属性名是一个合法的js标示符而且不是保留字的话就不用引号括起来。特殊情况例如:"my-name"这种的话,因为js中的标示符中包含连接符(-)是不合法的,所以要用引号去包住,如果用下划线(_)就不用了。

对象字面量属性值里面可以在嵌套对象的。

var Person = {
    name: "john",
    Person2: {
        age: 16
    }
};
检索

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

person["name"];
person.name;

如果属性值没有的话,我们可以用||充当默认值。

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

尝试从undefind对象里取值将会导致TypEerror异常。可以通过&&运算符来避免错误。

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

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

// 例子一
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);
    }
};

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85562.html

相关文章

  • javascript语言精粹学习笔记 - 继承

    摘要:但采用构造器调用模式,即是使用了前缀去调用一个函数时,函数执行的方式会改变。对象包含构造器需要构造一个新的实例的所有信息。构造器的变量和内部函数变成了该实例的私有成员。 JavaScript 是一门弱类型语言,从不需要类型转换。对象继承关系变得无关紧要。对于一个对象来说重要的时它能够做什么,而不是它从哪里来。 阅读《javascript语言精粹》笔记! 伪类 js的原型存...

    harriszh 评论0 收藏0
  • javascript语言精粹学习笔记 - 数组方法实现

    摘要:在中数组是经常被使用到的,我们除了要学习数组的方法,还需要了解诶一下某一些方法是如何来实现的。然而我看了语言精粹中方法的一章,想记录下书上的代码,以便加深印象。方法移除数组中的第一个元素并且放回该元素。 在js中数组是经常被使用到的,我们除了要学习数组的方法,还需要了解诶一下某一些方法是如何来实现的。然而我看了《javascript语言精粹》中方法的一章,想记录下书上的代码,以便加深印...

    felix0913 评论0 收藏0
  • 【阅读笔记javascript 语言精粹

    摘要:前言由于最近的项目用到了一些的代码,所以我带着好奇心,认真阅读了这本书,粗略地了解语言的基本结构和特性,对于一些不熟悉的新概念,以记录的形式加强印象,也是对学习的反思总结。 前言 由于最近的项目用到了一些js的代码,所以我带着好奇心,认真阅读了这本书,粗略地了解js语言的基本结构和特性,对于一些不熟悉的新概念,以记录的形式加强印象,也是对学习的反思总结。 一、字面量(literals...

    tangr206 评论0 收藏0
  • javascript语言精粹学习笔记 - 递归函数

    摘要:递归函数就是会直接或者间接地调用自身的一种函数。一般来说,一个递归函数调用自身去解决它的子问题。书上第二个例子是说递归函数可以非常高效率的操作树形结构,比如。有一些语言提供了尾递归的优化。好运的是,给我们带来了尾递归,详细迎接使用尾递归。 递归函数就是会直接或者间接地调用自身的一种函数。递归是一种强大的编程技术,它把一问题分解为一组相似的子问题,每一个都用一个寻常解去解决。一般来...

    Ryan_Li 评论0 收藏0
  • JavaScript 语言精粹》读书笔记 - 函数

    摘要:语言精粹读书笔记第四章函数函数字面量函数字面量包含个部分第一部分,保留字第二部分,函数名,它可以被忽略。这个超级延迟绑定使得函数对高度复用。构造器调用模式一个函数,如果创建的目的就是希望结合的前缀来调用,那它就被称为构造器构造。 《JavaScript 语言精粹》 读书笔记 第四章 函数 Functions 函数字面量 函数字面量包含4个部分: 第一部分, 保留字 function...

    wdzgege 评论0 收藏0

发表评论

0条评论

LoftySoul

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<