自定义类
1、快速入门
1)使用面向过程思想定义一个人的信息(姓名、年龄、婚否)
以上程序可以用于描述一个人的信息,但是从程序的上下文可知:其信息的表述并不够准确,因为name、age、marry都同属于一个人的信息,但是从以上程序中三个变量并没有任何联系。
2)使用面向对象思想定义一个人的信息(姓名、年龄、婚否)
2、类的定义
特别说明:在Javascript中,没有定义类的基本语法(没有class关键词)。只有function,当我们在系统中定义一个function函数,系统会自动认为该函数是同名类下的构造函数,相当于隐式创建了一个同名类,我们也把这个函数称之为"构造器"。
3、类的实例化流程
在Javascript中,可以通过new 类名()的形式来实例化类并生成对象,其在运行过程中主要执行了以下两个步骤:
① 在堆内存中开辟内存空间
② 执行类下的同名构造函数
4、创建对象的目的
创建对象的最根本目的:就是为了保存更多的数据,在面向对象中可以通过属性来保存数据。
5、定义属性
在Javascript中,可以通过以下两种形式来完成对属性的定义:
对象.属性
或
对象['属性']
创建类之后实例化一个对象,之后就可以给对象添加属性了,添加属性有两种方法(p.属性名)(p[属性名]),访问也可以使用这两种方法
运行结果:
6、属性的类型
在Javascript中,对象的属性理论上可以保存任何类型的数据,常用的有:
数字 :Number类型(如年龄)
字符串 :String类型(如姓名)
布尔值 :Boolean类型(如婚否)
对象 :window.document
问题:如果在Javascript中定义一个function函数,其是以面向过程方式调用的还是以面向对象的方式调用呢?
说明:其实在Javascript中一切都是对象:
var i = 10; //Number类的实例
var str = 'hello'; //String类的实例
var flag = true; //Boolean类的实例
在全局中定义的函数(如display)相当于在window对象下添加一个叫做display的属性。
display()的调用就相当于window.display()
7、三大关键词
- alert( typeof p ) : 判断一个变量的数据类型
- alert( p.constructor ) : 返回当前对象的构造函数(构造器)
- alert( p instanceof person ) :判断对象是否是某个类的实例,返回布尔类型
8、对象在内存中的存储形式
在Javascript中,变量在内存中的存储形式主要与当前变量的数据类型有关,一共分为两大类:
1)值类型
String类型、Number类型、Boolean类型、NULL类型、Undefined类型
2)引用类型
Object类型
记住:由于值类型的数据都比较简单,如果放在堆内存中,每次读取都需要耗费非常多的系统资源,所以其存储于栈内存中。而对于Object对象类型的数据通常存储于堆内存。
9、对象在内存中存储形式思考题
思考题1:如果创建第二个对象,会拥有name和age属性吗?
答:不会,原理如下图所示:
思考题2:如果创建第二个对象p2,使用p1为p2赋值会怎样?
答:p2会拥有p1对象的name和age属性,原理如下图所示:
思考题3:在思考题2的基础上,如果删除了p2对象,是否会对p1对象产生影响呢?
答:不会受到影响,原理如下图所示:
10、面向对象中的this
回顾在php中,如果实例化一个对象,其会自动继承类中的所有属性和方法。
在Javascript中,对象的属性都是先定义后添加(动态添加),如下图所示:
问题:我们可不可以让Javascript中的实例化对象也自动拥有类中属性和方法呢?
答:使用this,在Javascript面向对象的构造函数中也存在一个特殊的对象this,根据谁使用了这个函数,其函数内部的this就指向谁的原则,构造函数中的this指向了当前实例化对象,所以可以借助此特性让自定义对象自动拥有类中的属性和方法,代码如下:
以上代码虽然可以让自定义对象自动拥有类中的属性和方法,但是其所有的属性都是一致的,这显然不合逻辑,可以使用传参的形式进行改进,如下图所示:
11、深入理解Javascript中的this
其实,在Javascript全局作用域中也存在一个特殊的this对象,其指向了全局的window对象,代码如下图所示:
12、this对象的相关思考题
思考题1:尝试理解以下代码
思考题2:观察以下代码,说出程序的运行结果
思考题3:观察以下代码,说出程序运行结果