记得大学java课的老师经常说:"万物皆对象"。
对象和类
支持面向对象编程(OOP)的语言通常以类(主要语言有Java)或原型(主要语言有JavaScript)的形式出现,然后使用继承用于代码重用和可扩展性。那些使用类的时候有两个主要概念:
- 类 –给定类型或对象类的数据格式定义和可用过程;也可能本身包含数据和过程(称为类方法),即类包含数据成员和成员函数
- 对象 –类的实例
对象有时对应于现实世界中发现的事物。例如,一只大雁有 "翅膀", "翅膀", "脚", "嘴", 等属性。接着识别这只大雁的动态行为,如:"飞行", "觅食", 等。这些行为都是这个对象(大雁)基于其属性而具有的动作。 究其本质,所有的大雁都具有以上行为,可以将这些属性和行为封装起来以描述大雁这类动物,因此,类实质上就是封装对象属性和行为的载体,而对象则是类抽象出来的一个实例
每个对象都是特定类的实例(例如,名称字段设置为“ Mary”的对象可能是Employee类的实例)。面向对象编程中的过程称为方法。变量也称为字段,成员,属性或属性。这导致以下术语:
- 类变量 –整体上属于类;每个只有一个副本
- 实例变量或属性–属于单个对象的数据;每个对象都有自己的副本
- 成员变量 –指的是由特定类定义的类变量和实例变量
- 类方法–整体上属于类,并且只能访问类变量和过程调用中的输入
- 实例方法–属于单个对象,并且可以访问被调用的特定对象的实例变量,输入和类变量
程序可以创建与运行相同类的许多实例,这些实例可以独立运行。对于在不同的数据集上使用相同的过程,这是一种简便的方法。 使用类的面向对象的编程有时称为基于类的编程,而基于原型的编程通常不使用类,但也可以使用相似的术语来定义对象和实例的概念。
基于类与基于原型
在基于类的语言中,预先定义了类,并根据这些类实例化了对象。如果从人类实例化了两个对象student和teacher,它们本质上都是人类,因此可以保证以相同的方式处理它们。
// java 代码 类的示例
class Person{
//属性是成员变量,私有化属性,使得其他对象不能直接访问属性
private String name;
private int age;
//参数及方法内定义的变量是局部变量
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
}
// student teacher 是完全不同的两个实例
Person student = new Person();
Person teacher = new Person();
JavaScript也许是最著名的基于原型的编程语言,它从原型进行克隆而不是从类继承(与基于类的编程相反)来实现面向对象的概念。虽然自ES6以来出现了Class的语法糖,但Class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已
ES6 的类,完全可以看作构造函数的另一种写法
class Point {
// ...
}
typeof Point // "function"
Point === Point.prototype.constructor // true
// 上面代码表明,类的数据类型就是函数,类本身就指向构造函数。
在基于原型的语言中,对象是主要实体。甚至不存在任何类。对象的原型只是该对象链接到的另一个对象。每个对象都有一个原型链接(只有一个)。可以基于已选择作为其原型的现有对象来创建新对象。如果存在对象水果,并且苹果和橙子都具有水果作为原型,则可以将两个不同的对象苹果和橙子称为水果。水果类的想法并不明确存在,但作为共享相同原型的对象的等价类。属性和方法的原型被委派至该原型中定义的等价类的所有对象。该对象单独拥有的属性和方法不能由相同等效类的其他对象共享;
// JavaScript代码 类的示例
function Person() { }
Person.prototype.name = '张三';
Person.prototype.age = 20;
Person.prototype.job = '程序猿';
Person.prototype.getName = function () {
console.log(this.name)
}
Person.prototype.setName = function (name) {
this.name = name;
}
// person1和 person2 是可以共用的
var person1 = new Person();
person1.setName('李四');
person1.getName();
var person2 = new Person();
person2.setName('王五');
person2.getName();
// 知道为什么返回true吗
console.log(person1.getName() === person2.getName())
我们将getName
,setName
直接添加到了Person的prototype属性中,构造函数变成了空函数。 Person.prototype对象的属性和方法是由所有实例共享,换句话说,person1和person2访问的都是同一组属性,和同一个getName,setName函数(这里就需要理解原型模式的工作原理了)。
总结
如何理解JavaScript中的面向对象:
参考文档
- wikipedia-Object-oriented_programming
- 《java从入门到精通》
- 《JavaScript高级程序设计》
- es6.ruanyifeng.com
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!