javascript --创建类

在开始这篇文章的主题之前,我先把之前对匿名函数的了解整理一下。

1. 匿名函数是一种没有名字的函数表达式。
2. 匿名函数有时候可以使代码变得更加简洁。
3. 在解析你的剩余代码之前声明式函数就已经被定义好了。
4. 函数表达式被解析的时候与普通代码一样级别,哪儿出现了函数表达式,解析到那里了才会去定义函数。
5. 我们可以将一个函数表达式(其实我觉得跟匿名函数一模一样)作为参数传给另外一个函数,也可以从函数中返回一个函数表达式。
6. function expression 实际上就是一个 function 的引用,所以我们在可以使用函数的地方使用 function expression.
7. Nested functions (嵌套函数)是一些被定义在函数内部的函数。
8. 嵌套的函数有自己的局部范围,比如嵌套函数中的变量就是局部变量。
9. Lexical scope 说明我们可以通过阅读我们的代码来决定变量的作用范围。
10. 要bind嵌套函数中一个变量的值,首先,在嵌套的函数中看有无定义,有则使用,如果没有就往父函数上找,直到全局范围为止。
11. 闭包是一个带着引用环境(reference function)的函数。
12. 在闭包被创建时,闭包就捕获到了范围内变量的值。
13. 函数体中的Free variables (自由变量)指的是定义在当前函数之外,却在当前函数中被使用的变量。
14. 如果在其他的场景中执行了闭包函数,那么该函数中变量的值取决于闭包所携带的环境。
15. 闭包经常被用于为事件处理捕获状态信息。

创建一个Object

我只前接触的创建一个对象都是使用var = {属性:属性值}这类的方法,使用这种方法创建对象放在小项目中倒是可以,可一旦遇到了比较大型的项目作业时,仍使用这种方法来创建对象就显得有点蹩脚了,毕竟这种方法很难实现我们创建许多个属性相同,类似这种形式的对象。亦或者说,使用这样的literal方法来创建许多属性相同的对象实在是需要写出许多相同的代码,使得代码变得不再简洁,并且容易遇到代码错误,拉下了开发的效率。


Paste_Image.png

下面隆重介绍 <b>Object Constructor</b>
使用这种对象构造器可以轻松解决上述代码重复、不简练的问题。

创建一个constructor

Paste_Image.png

<b>示例一:</b>

var duck = {
  type: "redheaded",
  canFly: true
}

将上面literal式创建对象的方法改写为构造器的形式, 示例如下:

function Duck (type, canFly) {
  this.type = type; // 类型
  this.canFly = canFly;  // 能不能飞
}

构造器的使用

如上所示,我创建了一个对象构造器Duck,那么接下来的问题是:
<b>我要如何来使用构造器呢?</b>

Paste_Image.png

通过这个构造器来创建一个对象,我们需要使用到new操作符。
以及该对象需要提供的实际参数值。

看完书中的例子,我们再来看看构造器Duck这个示例。

<b>示例二:</b>

function Duck (type, canFly) {
  this.type = type; // 类型
  this.canFly = canFly;  // 能不能飞
}
var samllUglyDuck = new Duck("天鹅", "可以飞得很高,很远");

同样,我们可以使用new操作符来创建一批此我们想要的对象。

<b>示例三:</b>

function Duck (type, canFly) {
  this.type = type; // 类型
  this.canFly = canFly;  // 能不能飞
}

var duck1 = new Duck("鸭子1","能飞");
var duck2 = new Duck("鸭子2", "不能飞");
var duck3 = new Duck("鸭子3", "能飞");

/* 通过循环创建一批对象出来 */
var ducks = [];  // 声明一个可用的数组
for (var i = 0; i <= 50; i ++) {
  ducks[i] = new Duck("眫鸭", "可以飞得很高,很远");
}


/* 使用literal式来创建三个鸭子 */
var duck5 = {
  type : "1",
  canFly : false
};
var duck6 = {
  type : "2",
  canFly : false
};
var duck7 = {
  type : "3",
  canFly : true
};
1. 这样我们是不是就创建了50只鸭子,并且都存放在了数组ducks里面了呢?
2. 我们会发现,数组中的所有Duck对象都具有相同的属性。
3. 使用构造器来创建对象是literal式创建对象相比,构造器constructor更优。

说说在使用构造器的时间,都发生了些什么?

结合这个语句来帮助理解:

var duck1 = new Duck("鸭子1","能飞");

观察这条语句的右手边部分,这一部分的关键从new开始。

1. 在代码执行时,new操作符首先创建了一个空的Object;
2. 接着,new操作符又为this指针分配新的对象Object,也就是例子中的Duck;
3. 当this设置好了之后,将函数需要用到的数据分别传入作为实参;
4. 函数Duck开始被激活,实参被分配到this所指向对象的对象属性。
5. 最后,一旦Duck中的函数体执行完毕,新的对象就创建成功了。new操作符会自动返回指向该对象的引用(指针),并按照语句所写的意思,将该new操作符返回的引用分配给了duck1,  所以我们没有必要在构造器中写上return语句。

为我们的Object添加方法

Paste_Image.png

为对象属性添加方法等同于为一个对象属性赋予一个匿名函数。

一些要注意的地方

从Object的constructor构造器我们得知,它其实也是一个函数,但我们却不能像对待函数那样来对待我们的构造器:

1. 按照约定俗成的说法,通常将构造器名称的首字母大写
2. 在构造体中,我们可以向对待函数体一样,任意地定义变量,使用循环等等事情,但有一点需要知道的是,不建议在构造体中写上你的任何return语句,因为使用构造器的目的是最终能创建对象,如果构造器中不慎被写上了return true,return 1等等这样的语句,会给构造器带来伤害,使得构造器不能正常地返回我们想要的对象。 

在使用构造器创建对象的时候,我们用到了new操作符。
如:

var duck = new Duck("天鹅", "可以飞得很高");
如果上面不使用new操作符,直接使用调用函数的方式来完成创建对象的任务,那么,我们的程序执行了之后会是什么样的呢?
Paste_Image.png

下面是对上图错误的解析:


Paste_Image.png
以下是我的翻译加深理解:
1. 记住在配置this变量之前,new操作符会去创建一个新的Object,接着再去调用构造器函数。如果没有使用new操作符,那么就意味着没有任何对象被创建。

2. 对象没有被创建,就说明this没有指向一个新的对象,有或者说,this此时指向的是我们的应用的全局对象(window)。

3. 如果没有使用new操作符,则构造器不会返回任何对象,也就没有什么可以去赋值给变量darkside。所以darkside 等同于 undefined。我们在darkside中调用play()方法时,就碰到了这种错误。

对象构造器并非完美

说这话的功夫,看着文章,JavaScript初学者可能也就看明白了,对象构造器也有不完美的一点:这一点来源于构造器参数(parameter)。
设想,我们写一个构造器便需要将一个对象所需要的属性都作为形参全部列到构造函数的参数列表中,以便传递进实际的值,要说这些属性五个、六个也还不算糟,但要遇上有十来二十个属性的对象,这得有多令人糟心呐……
再设想,如果一个函数的参数列表包含了许多变量,那这样的代码写起来该有多累呀,这样的代码看起来多不入目呀,这样的函数一旦被调用,我们又是得多小心才能保证一个数据不会被赋值到错误的变量上啊!

好在“世上无难事,只怕有心人”。通过看书——《Head First JavaScritp》的第十二章,我看到了针对这种问题的解决方法。

使用literal式创建对象的方法这个时候就用上了。它将与构造器相结合,用更加易懂的方式帮助我们理解。

下面听我新接触到创建对象的方法:

  1. 用literal字面量方式来创建一个对象,其中包括了对象应具备的属性或方法。
  2. 按照创建对象构造器的步骤正常进行,但是构造器的形参列表不再是好多个变量(相应对象的属性),而是把之前通过字面量方式创建出来的对象直接传入。
  3. 最后使用构造器创建对象,调用构造器函数时,传递给该函数的参数就可以直接使用第一步中literal式的对象。
如何知道对象的类型

要知道在javaScript中,存在可以检测基本数据类型的操作符typeof。
typeof可以返回不同变量所对应的数据类型,可是它不认识比如构造器为Dog或Cat的Object。用另外一种说法是:使用Dog构造器得到的对象在typeof看来其实就只是一个Object,它不知道这个Object就是Dog的一个实例(instance)。

如果我们在某些时候很想要知道一个对象所属的类型,那要怎么办呢?毕竟typeof在这一点上帮不到我们。
在学习JavaScript之前,我接触过Java的SE部分。在Java中,要想检验测试一个对象实例所属的类时,我们通常会借助instanceof操作符,通过其返回值的真假来判断分析。而在JavaScript中也是如此,我们依然可以借助instanceof操作符来检验对象实例的类型,比如:
我们使用了Cat构造器创建了cat对象实例,那么,

cat instanceof Cat

cat instanceof Cat就会返回true,因为cat确实是由Cat构造器创造出来的,确实属于Cat一类。反之,instanceof操作符便会返回false。

添加对象属性和删除对象属性

使用构造器创建的对象与使用字面量方式创建的对象其实都具有相同的性质,都可以随意为我们的对象添加属性或者删除属性,而且其操作方式也是一致的。

Paste_Image.png

我们有时会担心,在添加或删除对象属性之后,这个对象实例还属于之前的那个类吗?
答案是肯定的,无论我们对这个对象的属性做出何等改变,都改变不了他生父就是他生父的事实。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,911评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,014评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,129评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,283评论 1 264
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,159评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,161评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,565评论 3 382
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,251评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,531评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,619评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,383评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,255评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,624评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,916评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,199评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,553评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,756评论 2 335

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,497评论 18 139
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,196评论 0 4
  • 感冒 头疼欲裂,一把鼻涕一把泪,身体上各种不爽,前段时间因为腰疼心情不舒服,后来又因为针灸可能可能还是怎样 ...
    局外人ng阅读 163评论 0 0
  • 一直以来都认为万事只能靠自己,只有勤奋付出坚持才能成功。最近才感受到,靠自己那是基于恐惧所作出的策略。真实才是最大...
    在云端01阅读 896评论 0 2
  • 作为上升射手的我,从15年至17年8月25日土星逆行,这三年时间一直处于被考验的状态。不管是亲情友情或者工作...
    陈开莺阅读 328评论 0 1