`
毒药001
  • 浏览: 5353 次
  • 性别: Icon_minigender_1
  • 来自: 昆明
最近访客 更多访客>>
社区版块
存档分类
最新评论

学习面向对象javascript(四)对象

 
阅读更多

 

 

 

 

之前,我们已经学习了javascript的基本数据类型,数组和函数。在下面的文章中,我们会了解到一些关于对象的知识。比如如何创建和使用对象,以及对象的构造函数等。

 

从数组到对象

我们大家都知道,数组就是一序列元素的组合,每一个元素有他对应的数字索引,从0依次递增。
对象和数组很相似,不同的是对象的索引是由你自己来定义的。索引不局限于用数字来表示,可以用比较好记的关键字来表示。作为对象的属性名。比如:

var hero = {
  breed: 'Turtle', 
  occupation: 'Ninja'
};

 

在这个对象中,包含了两个属性名,也就是索引 ,"breed" "occupation"

在对象中,属性名可以用单引号或者双引号引起来,也可以不加。比如:

var o = {prop: 1};
var o = {"prop": 1};
var o = {'prop': 1};

一般的,为了节约js文件的大小,通常把引号省略了。但是在有些情况下,又必须加:

  • 如果属性的名字是javascript的保留字时,必须加引号;
  • 如果属性的名字中包含空格或者(数字、字母、下划线)以外的字符,必须加引号;
  • 如果属性名以数字开头时,也必须加引号。

总之,如果你使用的属性名不符合javascript中变量名的定义的话,你都必须加引号。比如:

var o = {
  something: 1, 
  'yes or no': 'yes', 
  '!@#$%^&*': true
};

在定义对象时,你可以用 [] 或者 {} 来定义。用 [] 的方式叫做数组字面标记法,用 {} 的方式叫做对象字面标记法。

元素,属性,方法

当我们说数组时,你可能会说数组中包含元素,当我们说对象时,你可能会说对象中包含属性。这在javascript中,并没有什么区别。
一个对象的属性可以是一个方法,因为方法也是数据。在这种情况下,我们说这个属性是一个方法。

var dog = {
  name: 'Benji', 
  talk: function(){
    alert('Woof, woof!');
  }
};

javascript 中,也可以在数组元素上定义方法并且可以执行,但是这种方式很少使用。

var a = [];
a[0] = function(what){
    alert(what);
};
a[0]('Boo!');

访问对象的属性

有两种方法可以访问一个对象的属性:

  • 用方括号[],比如hero['occupation']
  • 用点号,比如hero.occupation

用点号可以方便我们读写,但是如果属性名是不合法的时候,用点号就不行。
我们继续看上面的hero对象:

var hero = {
  breed: 'Turtle',
  occupation: 'Ninja'
};
 
// 用点号访问属性
hero.breed;  // "Turtle"
// 用方括号访问属性
hero['occupation']; // "Ninja"
// 访问不存在的属性,将会返回undefined
'Hair color is ' + hero.hair_color;  // "Hair color is undefined"
 

对象可以包含任何数据,包括对象。

var book = {
  name: 'Catch-22',
  published: 1961,
  author: {
    firstname: 'Joseph',
    lastname: 'Heller'
  }
};

要获得 author 中的 firstname 属性的值,可以这样访问:

book.author.firstname;  // "Joseph"

或者用方括号

book['author']['lastname'];  // "Heller"

也可以混合使用

book.author['lastname'];  // "Heller"
book['author'].lastname;  // "Heller"

有时候我们要访问的属性名是未知的。那么在运行时,可以把属性名动态的存在一个变量上。然后用方括号的方式访问。这种情况下,用点号是不行的。

 

var key = 'firstname';
book.author[key];  // "Joseph"

调用对象的方法

可以说,方法只不过是特殊的属性,所以,你可以像访问属性一样访问方法。

var hero = {
  breed: 'Turtle',
  occupation: 'Ninja',
  say: function() {
    return 'I am ' + hero.occupation;
  }
}
hero.say();  // "I am Ninja"
hero['say']();  // "I am Ninja"

修改属性和方法

由于javascript是一种动态语言,它允许使用者在任何地方修改对象的属性和方法。包括添加,删除属性等。

我们可以先传进一个空的对象来试试:

var hero = {};

 

然后访问一个不存在的属性:

typeof hero.breed;  // "undefined"

添加一些属性和方法在对象中:

hero.breed = 'turtle';
hero.name = 'Leonardo';
hero.sayName = function() {
    return hero.name;
};

 

试一下调用对象的方法:

hero.sayName();  // "Leonardo"

删除属性:

delete hero.name;  // true

然后再次调用刚才的方法:

hero.sayName();  // reference to undefined property hero.name

在前面的例子中,sayName方法使用的是hero.name来访问hero对象的name属性。其实可以使用this关键字来访问。

var hero = {
  name: 'Rafaelo',
  sayName: function() {
    return this.name;
  }
}
hero.sayName();  // "Rafaelo"

 所以this在这里表示当前对象。

构造函数

创建对象的另一种方法是使用构造函数。

function Hero() {
  this.occupation = 'Ninja';
}

为了创建对象,我们将会使用到new操作符;

var hero = new Hero();
hero.occupation; // "Ninja"

使用构造函数的好处是,它可以接受参数。

function Hero(name) {
  this.name = name;
  this.occupation = 'Ninja';
  this.whoAreYou = function() {
    return "I'm " + this.name + " and I'm a " + this.occupation;
  }
}
var h1 = new Hero('Michelangelo');
var h2 = new Hero('Donatello');
h1.whoAreYou();  // "I'm Michelangelo and I'm a Ninja"
h2.whoAreYou();  // "I'm Donatello and I'm a Ninja"

习惯上,我们会把构造函数的第一个字面大写,以便和其他方法区别开。如果你在调用一个构造方法时,忘记写new操作符,这个不会报错,但是代码不会为你创建一个对象出来。

var h = Hero('Leonardo');
typeof h;  // "undefined"

这样,Hero只不过是像调用其他方法一样,方法中没有return。所以默认return了undefined并赋值给变量h。

全局对象

实际上,环境(比如浏览器)会为我们提供一个全局的对象。我们在代码里声明的全局变量,其实都是这个全局对象的属性。对于浏览器而言,这个全局变量就是window。
你可以定义一个全局变量,然后用各种方式从window上访问试试。

var a = "aaaaa";
window.a;  // "aaaaa"
window['a'];  // "aaaaa"

就刚才的那个例子,Hero没有用new操作符。然而Hero方法里又使用了this这个关键字,this表示当前的对象,其实这个时候,当前对象就是这个全局对象。所以,此对象上会有一个name属性。

function Hero(name) {
    this.name = name;
}
var h = Hero('Leonardo');
name;  // "Leonardo"
window.name;  // "Leonardo"

可以发现,name这个属性加到了window上面了。
所以,只有在使用了new关键字时,才能返回这个new出来的对象给变量h,那么这个时候,this所指的对象就是这个新的对象了。

 

constructor属性

其实在我们创建对象是,有一个特殊的属性会做一些幕后的工作。它就是constructor。它是构造方法的一个引用属性,我们也可以用它来创建对象。

function Hero(name) {
    this.name = name;
}
var h2 = new Hero('Leonardo');
h2.constructor; // Hero(name)

可以看到,它其实就是构造方法。
由于constructor引用的是一个方法,说以我们可以往这个constructor里面传入参数来建立一个新对象。

var h3 = new h2.constructor('Rafaello');
h3.name;  // "Rafaello"

但是,值得注意的是,如果使用字面方式来定义一个对象的话,那么他的constructor属性将会指向他的内置对象Object的构造方法。

var o = {};
o.constructor;  // Object()
typeof o.constructor;  // "function"

instanceof

使用instanceof关键字,可以用来检测对象是否是由某个特定的构造方法创建的。

function Hero(){}
var h = new Hero();
var o = {};
h instanceof Hero;  // true
h instanceof Object;  // true
o instanceof Object;  // true

返回对象的函数

其实,我们还可以用另外的方式来创建对象,就是在函数中返回对象。
比如下面这个简单的factory方法

function factory(name) {
  return {
    name: name
  };
}
var o = factory('one');
o.name;  // "one"
o.constructor;  // Object()

实际上,我们还可以改变构造函数的默认行为。
通常的:

function C() {this.a = 1;}
var c = new C();
c.a;  // 1

这样一个构造函数,方法最后会返回this这个对象。

function C2() {this.a = 1; return {b: 2};}
var c2 = new C2();
typeof c2.a;  // "undefined"
c2.b;  // 2

但是现在在构造函数中返回的是另一个对象。注意这里只有当函数返回的是另一个对象是,这个返回this的默认行为才会被改变。

对象的传递

当我们复制一个对象或者把对象传入函数的时候,其实他传递的是一个对象的引用。因此,对引用所做的任何改变,都会改变实际的对象。

var original = {howmany: 1};
var copy = original;
copy.howmany; // 1
copy.howmany = 100;
original.howmany;  // 100

把对象传入函数也是一样的。

var original = {howmany: 100};
var nullify = function(o) {o.howmany = 0;}
nullify(original);
original.howmany;  // 0

对象的比较

当比较两个对象是否相等时,只有这两个引用的对象是同一个的时候,才返回true。

var fido  = {breed: 'dog'};
var benji = {breed: 'dog'};
benji === fido;  // false
benji == fido;  // false

如果定义一个新的变量mydog,然后把其中一个对象benji赋值给他,那么benji就会和mydog指向同一个对象。

var mydog = benji;
mydog === benji;  // true
mydog === fido;  // false

 

在下一篇文章中,会对javascript的内置对象做一些说明。

分享到:
评论

相关推荐

    面向对象JavaScript精要(英文原版pdf)

    《面向对象JavaScript精要》是一本非常有价值的书籍,不仅适合初学者入门,也适合有一定经验的开发者进阶学习。通过学习本书,读者可以全面掌握面向对象编程的基本概念,并学会如何将这些概念应用到JavaScript中,...

    面向对象javascript

    面向对象JavaScript教程 面向对象JavaScript是一种编程范式,它将JavaScript脚本编写转换为面向对象的思想。面向对象的JavaScript开发可以极大地提高开发效率和代码健壮性。 面向对象的JavaScript的特征包括: * ...

    Javascript面向对象编程.

    JavaScript是一种广泛应用于Web开发的脚本语言,尤其在前端领域占据着核心地位。面向对象编程(Object-Oriented Programming,OOP)是...学习这些材料将有助于深入理解JavaScript的面向对象编程,提升你的编程技能。

    JavaScript学习深入—面向对象编程

    ### JavaScript学习深入—面向对象编程 #### 一、JavaScript中的类型概述 JavaScript作为一种动态的、弱类型的语言,其核心特点之一在于它灵活的对象模型。尽管JavaScript的基础架构支持面向对象编程(OOP),但在...

    javascript 经典面向对象设计

    ### JavaScript经典面向对象设计 #### 标题与描述解析 标题“JavaScript经典面向对象设计”指出...通过学习本书中的概念和技术,开发者可以更好地理解如何利用面向对象编程的优势,构建出更加健壮和灵活的应用程序。

    javascript面向对象编程.pdf

    总而言之,学习现代JavaScript面向对象编程,有助于开发者在认识这门语言演化的基础上,运用面向对象的设计和编程模式来构建更加健壮和可维护的JavaScript应用程序。同时,测试和调试是保证代码质量不可或缺的环节,...

    JavaScript面向对象编程指南.pdf

    JavaScript面向对象编程是指在JavaScript语言中使用面向对象的方法来编写程序。JavaScript是一种高级的、解释型的编程语言,它支持面向对象的编程范式,允许开发者创建对象、使用继承和多态等面向对象的特性。以下是...

    面向对象Javascript核心支持代码分享

    在讨论面向对象JavaScript开发时,核心支持代码是构建面向对象特性的基石。为了深入理解这一概念,我们首先要探讨面向对象编程(OOP)的基本原理及其在JavaScript中的实现方式,然后将通过分析提供的代码片段,揭示...

    JavaScript面向对象编程指南(第2版).rar

    JavaScript是一种广泛...通过深入学习这本《JavaScript面向对象编程指南(第2版)》,开发者不仅能掌握JavaScript的面向对象编程基础,还能了解到实际项目中如何有效地运用这些知识,提升编程技巧和解决问题的能力。

    js 面向对象实例

    每个JavaScript对象都有一个`__proto__`属性,指向创建该对象的构造函数的原型。原型对象也是一个对象,可以通过`prototype`属性来访问。我们可以在原型上定义方法,这样所有实例都可以访问这些方法: ```...

    javascript面向对象框架

    MooTools提供了许多实用的工具和功能,比如Element、Fx、Events、Class等模块,这些模块使得开发人员能够轻松地处理DOM、动画效果、事件以及创建复杂的JavaScript对象。 1. **MooTools的Class系统**:MooTools的...

    JavaScript面向对象精要(英文版)

    ### JavaScript面向对象精要 #### 一、概述 ...通过学习本书,开发者能够更好地理解JavaScript的底层工作原理,掌握高效的编码技巧,并能灵活运用面向对象的设计原则来构建可维护性强的应用程序。

    JavaScript面向对象基础.ppt

    8.3.1 JavaScript对象模型 JavaScript有全局对象、内置对象、宿主对象等层次结构,如DOM(文档对象模型)和BOM(浏览器对象模型)。 8.3.2 客户端对象层次介绍 客户端对象层次主要涉及浏览器提供的对象,如window、...

    第15章 javascript面向对象与原型

    最后,面向对象的基础知识也是不可或缺的,由于JavaScript的面向对象实现方式比较特殊,所以学习者需要了解正统的面向对象编程基础。 创建对象是面向对象编程的基础。在JavaScript中创建对象有多种方式,最简单的一...

    学习javascript面向对象 javascript实现继承的方式

    在JavaScript中,面向对象编程是通过构造函数、原型链和继承实现的。继承是面向对象编程的核心概念之一,它允许我们创建一个新对象,该对象继承现有对象的属性和方法。在JavaScript中,实现继承有多种方式,每种方式...

    JavaScript面向对象编程案例

    学习JavaScript面向对象编程,不仅有助于理解代码的结构和复用性,还有助于提高编程效率和代码质量。通过阅读和实践这些案例,你可以逐步掌握如何创建、继承和操作JavaScript对象,从而成为一名更出色的JavaScript...

Global site tag (gtag.js) - Google Analytics