JavaScript 中的引用类型、类与继承概念辨析
依旧是梳理基础概念。
学校组织的西安生产实习第二天,雨依旧淅淅沥沥的下。
疑问
- 引用类型与对象的关系
- 创建对象的方法是一堆什么鬼
- 原型属性与实例属性
- 创建对象与继承都用到了原型,区别是什么
引用类型
- 在 ECMA 中,引用类型是一种数据结构,用于将数据和功能组织在一起,也常常被称为类。
- 引用类型的值是存在内存中的对象。对象在 JavaScript 中被称为引用类型的值。
- 引用类型的值是引用类型的一个实例。
对象
- ECMA-262 把对象定义为:无序属性的集合,其属性可以包含基本值、对象或者函数。对象是没有特定顺序的值。
- 对象在 JavaScript 中被称为引用类型的值。
- 函数实际上是 Function 类型的实例,因此函数也是对象。而这一点正是 JavaScript 最有特色的地方。由于函数是对象,所以函数也拥有方法,可以用来增强其行为。
- Object 是一个基础类型,其他所有类型都从 Object 继承了基本的行为。
创建对象的方法
-
与其引用类型有关
-
虽然 Object 构造函数或对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点,使用一个接口创建很多对象,会产生大量的重复代码。
-
新对象是使用 new 操作符后跟一个构造函数来创建的。构造函数本身就是一个函数,只不过该函数是出于创建内对象的目的而定义的。
工厂模式
- 工厂模式虽然解决了创建多个相似对象的问题,但是却没有解决怎样知道一个对象类型的问题。
构造函数模式
-
Object 和 Array 这样的原生构造函数,在运行时会自动出现在执行环境中。此外,也可以创建自定义的构造的构造函数,从而定义自定义对象类型的属性和方法。
-
创建自定义的构造函数意味着将来可以将它的实例标识为一种特定的类型,解决了工厂模式的弊端。
如下所示:
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function () {
alert("this.name");
}
}
var person1 = new Person("King", 19, "Doctor");
var person2 = new Person("Gray", 20, "Teacher");
person1 instanceof Object // true
person2 instanceof Person // true
person1 instanceof Object // true
person1 instanceof Person // true
使用构造函数的 主要问题 ,就是每个方法都要在每个实例上重新创建一遍。
原型模式
-
原型上定义的属性或者函数可以被所有实例共享。
-
构造函数一旦实例化,定义在构造函数上的属性和方法与实例便没有了关系。这时候只有实例与原型之间的联系。
-
原型模式除了创建自定义类型方面,还同样用在原生的引用类型。所有引用类型(Array、String、Object等等),都在其构造函数的原型上定义了方法。例如,在
Array.prototype
可以找到sort()
方法,而在String.prototype
可以找到substring()
方法 -
原型模式的弊端正是由其共享性决定的。
使用构造函数的对象 与 继承的区别
构造函数、原型、实例的关系
- 每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。
- 我原本以为:构造函数与原型其实是纵深上的关系。但是事实上是并列的关系。
继承
- ECMAScript 将原型链作为实现继承的主要方法,基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法,是通过一个类型的实例复制给另一个构造函数的原型实现的。
思考
-
应该认认真真的学一个面向对象语言,比如 C++。后悔上课时没有认真学习,导致现在对对象理解不是很透彻。通过 JavaScript 来了解面向对象的概念是在是痛苦。
-
从《高程》中可以看出,对于对象的创建,是从工厂模式一步一步完善起来的。