1、对象
1.1 什么是对象?
现实生活中:万物皆对象,对象是一个具体的事物,实实在在看得见摸得着的实物。例如,一本书、一辆汽车,一个人都可以称之为对象,一个数据库,一张网页,一个与远程服务器的链接也可以是对象。
为了能够能更加直白的看出什么是对象,我们不妨举一些例子:
# 1、明星(不是对象,范围太大了,需要具体到一个“个体”)
# 2、周星驰(是对象,已经具体到了一个“个体”)
# 3、女朋友(不是对象,还是因为范围太大)
# 4、黄海波(是对象,具体到了一个“个体”)
# 5、班主任(不是对象,范围太大,需要具体到一个“个体”)
# 6、咱班的班主任(是一个对象,具体到了一个“个体”)
# 7、游戏(不是对象,游戏的范围太大)
# 8、刺激战场(是对象,具体到了一个“游戏”)
在JavaScript中:对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数组、函数等。
抓住关键词:
# 对象是由"属性"和"方法"组成的
# 属性:事物的"特征",在对象中用属性来表示。(常用名词)
# 方法:事物的"行为",在对象中的方法来表示。(常用动词)

总结:什么是对象? 对象是一个事物,一个实实在在存在的事物,在我们JS里面,对象由两部分组成,一个叫属性,一个叫方法,属性就是外在的特征,方法就是外在的行为。
1.2 为什么需要对象?
我们知道,要保存一个值时,可以使用变量,保存多个值(一组值)时,可以使用数组,那么如何需要保存一个人的完整信息呢?我们会用到什么?没错,我们可以使用对象来进行保存。
为什么不适合用数组的方式进行储存个人的完整信息呢?
例如,将“张三丰”的个人信息保存在一个数组中的方式如下:
var arr =["张三丰","男",128,154]
通过上面这个数据你或许能马山反映出,前面两个数据,第一个是人名,第二个是性别。那么请问第三个数据和第四个数据代表的是什么呢?如果在没有描述的情况下,是不是特别懵逼。
或许你会说,我们可以给位置赋予含义不就好了吗?比如说位置1代表的是名字,位置2表示的是性别,位置3表示的是年龄,位置4表示的是身高。只要记住位置不就好了吗?
首先,如果有一百个数据同时在这个数据中会怎么样呢?难道还用位置的方式来记忆吗?显然这样是不合理的,这谁能记住呢?难道为了这一点,我们特意去编写一个字典用来查询吗?这样非常的傻。
其次,通过位置的方式进行储存的话是非常的危险的,一旦服务端的小哥哥给你来个倒序,你就傻眼了,数据和位置发生了错乱。因此,想通过位置来分辨属性的含义是极其不靠谱的。从而说明了通过数组的方式来储存个人信息的完整数据是非常不合适的。
但是储存多种数据的需要是存在的,那么可以提供什么样的方式可以既储存数据,且能够区分数据的属性呢?这个时候就出现了“对象”。对象既能储存数据,且能够对每一个数据进行设置属性。
通过JS中的对象表达结构更清晰,更强大。可以让人感觉到一目了然。
张三丰的个人信息在对象中的表达结构如下:
张三丰.名字 = "张三丰" ;
张三丰.性别 = "男" ;
张三丰.年龄 = 128 ;
张三丰.身高 = 154 ;
那么我们转换成代码的话,是下面这样色的。
person.name = '张三丰';
person.sex = '男';
person.age = 128;
person.height = 154;
从上面的对象编写方式可以看出,我们可以通过name、sex、age、height属性的方式就能直观的区分出数据的含义,从这一点还能看出什么呢?
# 通过上面的代码可以看出,对象是可以存储数据的,明白这一点,在日后的编程中,非常的重要。
总结:为什么需要对象?是为了让数据表达的更加清晰,可以让别人一眼就能看出这个数据是用来做什么用的。
2、创建对象的三种方式
上一小节中,我们知道了为什么需要对象,以及使用对象的好处。那么接下来我们看一下创建对象的三种方式。以及怎么去使用对象。
前情提要:在JavaScript中,现阶段我们可以采用三种方式来创建对象(Object);
# 1、利用“字面量”创建对象
# 2、利用“new Object”创建对象
# 3、利用“构造函数”创建对象
2.1 利用"字面量"创建对象
接下来我们研究一下创建对象的第一种方式:通过字面量的方式创建对象。
对象字面量:就是花括号{ }里面包含了表达这个具体事物(对象)的属性和方法。
前期准备工作,为了能让浏览器执行代码结果,因此需要我们准备结构型代码。

后续我们将在红色框下进行演示创建对象的具体流程。
2.1.1 如何创建一个空的对象?
其实非常的简单,其实像创建一个空数组的方式,如下所示。

2.1.2 字面量创建对象的方式
下面这个就是具体利用字面量创建对象的形式

创建完成之后,我们需要知道一些细节,比如:细节一、创建的属性和方法都是编写在花括号里面的。

细节二、不管是属性还是方法,用的都是
键值对的方式编写的

细节三、多个属性或者对个方法,中间是用逗号隔开的

细节四、方法冒号后面跟的是一个匿名函数

2.1.3 如何使用对象?
# 对象中“属性”的使用
第一种方式为:对象.属性名

运行一下,看下运行的结果;

第二种方式为:对象名['属性名']

运行一下,看下运行的结果;

# 对象中“方法”的使用
方法的使用: 对象名.方法名

运行一下,看下运行的结果;

2.1.4 变量、属性、函数、方法的区别
# 变量和属性的对比
首先我们看一下,变量的定义和使用方式以及属性的定义和使用方式

运行看一下,你会发现输出了你想要的结果。

那么我们分析一下,变量和属性的区别
## 相同点
变量和属性的相同点:他们都可以用来存储数据;

## 不同点
变量和属性的不同点①:变量需要单独声明,而属性不需要单独声明。
# 需要注意的是所谓声明,就是前面要不要加var这个关键词,别想的太复杂。

变量和属性的不同点②:变量需要单独赋值,而属性不能赋值。
# 需要注意的是所谓赋值,其实就是要不要加“=”(等于号)的意思。

这里我稍微说明一下,不管是“声明”,还是“赋值”,他们不过是一个描述信息,代表的是一个特性。就像上面描述的一样,你大可将“声明”理解成前面有没有直接用“var关键词”,将“赋值”理解成后面有没有跟着“等于号”,虽然说“声明”和“赋值”只看文字,非常的晦涩难懂,本质上就是一种描述某一个特性而已。在编程书籍上常用来作为学术名词使用。在这里稍微说明一下,避免产生疑问。
变量和属性的不同点③:变量直接使用变量名,属性在对象里面,使用的时候,用对象名.属性

# 函数和方法的对比
首先我们看一下,函数的定义和使用方式以及方法的定义和使用方式

运行看一下,你会发现输出了下面这样的结果。

接下来,我们不妨分析一下方法和函数的区别在哪里?
## 相同点
方法和函数的相同点在于:都可以在内部编写逻辑代码。

## 不同点
方法和函数的不同点①:方法编写在对象的内部,而函数可以在外部直接编写

方法和函数的不同点②:方法后面跟的是匿名函数,而函数是存在名称的,可以看出函数的名称为“fn”

方法和函数的不同点③:方式是通过 对象.方法()来进行使用的,而函数可以直接通过方法()来使用

2.2 利用"new Object"创建对象
接下来我们研究一下创建对象的第二种方式:就是通过new Object的方式来创建对象。
下面我们不妨看一下需要如何使用new Object的方式创建对象。

# 说明一下,为什么此刻突然之间将编写工具换成了“微信开发者工具”,这是因为我考虑到这个工具的字体更加美观。其实编写HTML的代码并不需要考虑非要哪一款工具,基本上所有的工具都能直接使用。最终的效果都是需要渲染到“浏览器”上进行查看结果的。因此不必纠结。为了能够在后续的文章中能够直观的看出代码的效果,一个美观的字体非常的重要。
保存一下,看下运行的结果。

接下来,我们不妨看一下里面的细节
细节一、每个"属性"和"方法"之间用分号结束

细节二、都是利用等号赋值的方法,来添加对象的“属性”和“方法”

细节三、注意new后面的
Object的"O"是大写的,不然会报错。

细节四、调用“属性”的方式和第一种方式(字面量创建对象的方式)是一致的

2.3 利用构造函数创建对象
接下来我们讲解一下创建对象的第三种方式:那就是通过构造函数的方式来创建对象。
在研究之前,我们需要搞清楚为什么需要使用构造函数?知其然不如知其所以然。
2.3.1 为什么需要使用构造函数?
这是因为前面两种创建对象的方式一次只能创建一个对象。构造函数可以创建多个对象。
为了能够形象的理解上面这句话,我们不妨举一个栗子。我们先给刘德华小朋友描绘一个画像。如下所示:

但是此时,我们需要给张学友小朋友也描绘一个画像,那么我们按照第一种方式创建对象的话,只能另起一个新的对象来进行编写。

那么请问另起一个对象进行存储的话会出现什么问题呢?
通过上面的代码可以看出name属性 ,age属性,sing方法都是重复的。上面只有两个人物其实还好,代码不是特别的多,但是倘若一个班主任,要给班上的50个同学都编写一个画像。那么这个方法会变成什么样子呢?
我们不妨稍微模拟一下,班上有4个同学,那么按照上面创建对象的方式来进行编写的话,会出现什么样的效果。

你会发现什么特点呢?
特点一、通过"字面量"的方式创建对象时,只能重新创建一个新的对象来储存自己的数据。
特点二、通过"字面量"的方式创建对象时,出现大量的冗余代码,重复性太高了。比如name属性等。
那么请问通过第二种方式来编写的话会是什么样子呢?
下面这个就是我们通过new Object的方式进行编写的对象。

不难发现,不管是通过字面量的方式创建对象还是通过new Object的方式创建对象,其实本质上都是一样的,会出现大量的冗余代码。
既然是这样的话,我们有没有更好的方式来解决上面这样的问题呢?
上面待解决的问题是:因为我们一次只能创建一个对象,里面会出现很多的属性和方法都是大量相同的,我们只能通过复制的形式进行使用。如果解决这个问题?
如果脑子比较灵活的小伙伴就想到了一个方法来解决上面的问题,**那就是将上面重复的属性或者方法封装到一个函数里面,从未达到复用的效果。**因此这种专门为了解决复用的函数,我们称之为**构造函数**。**(构造函数就是把对象里面的一些相同的属性和方法抽象出来封装到函数里面)。**
为什么还要特意的给他取一个专有的名称呢?
这是因为这个函数里面封装的不是普通的代码,而是对象。
'函数'和'构造函数'的区别:
# 函数内部编写的是普通的代码
# 构造函数里面封装的是对象
2.3.2 构造函数的语法格式
构造函数:是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new运算符一起使用。我们可以把对象中的一些公共的属性和方法抽离出来,然后封装到这个函数里面。
下面我们看一下构造函数的语法格式:
① 声明构造函数
第一步、编写一个正常的函数样式

# 你会发现这一步其实和编写其他函数没有什么不同。
第二步、这里开始就和普通函数的样式有些不一样了,需要加上
this.表示的是当前的,具体的代码如下:

② 使用构造函数
第三步,需要特别注意的一点是,如何调用构造函数的语法格式?

2.3.3 举例说明
为了能够更好的理解构造函数,我们不妨就拿之前编写的四大天王的画像作为示例,来讲解构造函数的实现。

第一步、将相同的属性和方法都抽离出来
-
可以看出相同的属性有:
name属性和age属性; -
而相同的方法有:
sing方法;
第二步、我们创建一个构造函数.

# 为了能够清晰的理解构造函数的知识点,这里先讲解有关属性的编写
# 有关属性的编写
为了方便理解,这里我们先处理相同属性的相关步骤!!!
第三步、我们需要将相同的“属性”名称都以
参数的形式填写在小括号里面

第四步、在构造函数内,用
this关键词来使用外部传入进来的属性值

第五步、我们不妨在外部使用一下构造函数?

第六步、将需要传递进去的属性值,都填入到小括号里面

其实这样就已经创建了刘德华的对象。为了验证这一点,我们可以传递给一个临时变量,并且打印出来。

第八步、这个时候保存一下,并且来到浏览器上看一下输出的结果。

通过上面输出的结果,可以告诉我们一件什么结论呢?结论是:调用构造函数,返回的是一个对象。

除了上面这一点以外,我们还可以得出一个结论:**构造函数并不需要使用"return"就可以返回结果;**这一点和普通的函数是非常不一样的。普通函数在返回结果的时候,必须使用
return才能返回结果。

然后我们思考一下,属性在使用时,传入的顺序是怎么样的。答案:如下所示。

# 从上面的代码中可以看出,构造函数能否使用到外部传入进来的数据,取决于程序员是否遵循构造函数的格式进行编写。否则外部传入进来的数据是无法被构造函数使用的。任何一个节点的丧失都会中断数据的传递。
如果此时我们需要将里面的刘德华这个名字取出来的话,那么需要如何使用呢?

为了验证这一点,我们不妨保存并查看一下浏览器中输出的结果。

到了这里我们就知道了如何创建刘德华的对象了,那么请问其他人的对象如何创建呢?

相比较以前的编写方式,你会发现是不是简洁了很多。我们只需要new一下构造函数,就能创建一个对象。

# 有关方法的编写
上面我们已经学习了有关属性的编写方式,但是你会发现怎么有关方法的编写没有讲解到呢?这是因为方法的格式有些奇怪。下面我们重点讲解一下有关方法的编写
第一步,我们需要构造函数中编写一个方法,如下所示。

第二步、我们会在方法内编写一个console.log(),特指运行一段逻辑代码。

第三步、这一点特别需要:我们需要在方法中的小括号上写在一个
参数。

第四步、我们在外部引用的时候,就是下面这个样子。(重点牢记)

# 上面这一点特性非常的重要,我们在日后的封装中起到了非常重要的作用。这一点决定了我们是否能够真正使用。
因为在封装的时候,我们一般都是将复杂的代码封装到构造函数里面的方法中,然后在外部只需要调用构造函数里面的方法即可,那么在使用构造函数内的方法的时候,就需要先new出来,然后再使用,就是上面的两段代码,缺一不可。否则不起作用。
那么我们不妨保存一下,并且看一下输出的结果。

我们看一下方法中的数据传递顺序是怎么样的?

最后我们完善一下,四大天王的人物画像。这样的话,方便我们对比前面我们编写的代码。

# 通过对比,你会发现使用“构造函数”来创建对象,最直白的效果就是减少了很多的代码,并且在维护上简单很多。倘若我们需要给人物画像添加新的方法或者属性时,只需要在构造函数进行新建,然后在调用测稍作修改即可。相比较前面两种创建对象的方式可以说好很多了。
运行一下,看下结果,你会发现四大天王都给你唱了一首歌。

# 其实知道了上面的特性,那么意味着你学会了使用构造函数的语法了。虽然说看上去很简单,但是一旦涉及到动手封装的时候,还是容易导致手忙脚乱的。建议多看几遍。如果出现了卡壳,再回来复习一下。
2.3.4 "构造函数"和"对象"的区别
-
构造函数:如Stars(),抽象了对象的公共部分,封装到了函数里面,它泛指某一大类,不难发现,其实这个就是Java中Class类的概念。
-
**创建对象:**如new Stars(),特指某一个,通过new关键字创建对象的过程,我们称之为对象的实例化。
我们可以用现实中的物品,去形象化的比喻什么是构造函数?什么是对象?

如果还是不是特别理解的话,我们可以结合我们前面说写的案例。

-
构造函数代表的是Star,也就是“明星”,而明星泛指一个大类。将对象的公共部分抽象出来。(泛指)
-
对象是一个具体的事物,代码中的对象就是刘德华,具体到了一个明星个人身上。(特指)
# 什么是实例化?
**实例化就是:我们利用构造函数创建对象的过程。**类似于将汽车设计图纸制造成一辆汽车的过程称之为实例化。

# 什么是实例?

3、new关键字
请问new关键字在构造函数里面到底起到什么样的作用?

第一步、当构造函数遇到new关键词之后,会在内存中创建一个空的对象。

第二步、构造函数内部的this就会指向刚才创建的空对象

第三步、执行构造函数里面的代码,然后给这个空对象添加属性和方法。

第四步、将对象返回(类似return的操作)

# 上面这四步就是new关键字的执行过程。
我们总结一下,看下new关键字在执行时会做的四件事情。

4、遍历对象属性
4.1 遍历对象属性的场景
接下来我们需要学习一下遍历对象的属性。在学习之前,我们需要搞清楚为什么要学习他?
为了能够理解这个原理,首先我们模拟一个场景。然后在深入的进行讲解,从而消化这个知识点。

如果按照之前学习的内容,我们首先会想到使用下面的方式进行输出想要的结果。

然后我们看一下输出的结果。

# 我们不妨思考一下,按照上面这样的方式进行编写的话,会出现什么问题呢?
1、需要一个一个的进行编写console.log的方式进行输出,非常的麻烦。
2、一旦需要输出的属性多了以后,你会发现需要编写的代码非常的多。换句话就是繁琐。

那么请问有什么更好的方式将对象里面的所有的属性都打印出来呢?

或许你会想到for循环。因为for循环也具有遍历的特点,可以考虑用for循环进行打印。
我们如果真的用for循环的话,你会发现对象内是无序号的,没有序号的。但是for循环是需要计数器的,因此传统的for循环是不能打印我们的对象属性的。
既然不能使用for循环的话,那么请问还有其他方法可以用来遍历对象属性吗?
答案是:我们可以通过for...in 语句进行操作。
for...in语句用于对“数组”或者“对象”的属性进行循环操作。(for in循环最好用于遍历“对象的属性”)
4.2 for...in循环的语法

语法看上去挺简单的,我们不妨运用到上面的案例中,会变成什么样子?

需要特别留意的是,我们在使用for in里面的变量时我们喜欢写成'k'或者'key'
为了深究for...in循环的特点,我们不妨打印一下变量k

# 可以看出打印“变量k”输出的结果为:“对象下的所有属性名”
显然上面这个并不是我们想要的结果,那么请问该如何遍历出对象下的属性值呢?

# 特别留意的是:这里使用的是obj[k],而不是使用obj['k'],obj[k]是不存在引号的,因为此处及其容易和属性的使用规则混淆在一起。因此,这边特别说明一下。
为了验证这一点,完全可以保存后,看一下输出的结果

4.3 探讨:可以遍历对象内的方法吗?
你会发现上面我们并没有对对象内的方法进行遍历,那么请问可以遍历对象内的方法吗?
答案是:可以的,只不过我们很少用for...in循环去遍历方法而已。
我们不妨模拟一下,遍历对象内的方法。

我们不妨运行一下,看一下显示的结果。

# 这个和遍历属性名的方式无异。
然后我们遍历一下属性值,侧重点看一下有关对象中的方法的显示效果。

运行一下,看下浏览器中的显示效果。

因此我们总结一下,for...in循环,既可以遍历对象的属性名,也可以遍历属性值。除此之外,如果我们想要遍历对象中的方法名,已经遍历对象中的方法值也是可以的。只是相对少见一些。

对应的文章链接:
链接:https://pan.baidu.com/s/1jpyknfyGGunvpeseVkHjdg
提取码:txny