什么是面向对象?
“面向对象”是一种编程范型,但是就像 exist
这个选项一样,我们还有很多其他的选择,比如函数式编程,响应式编程编程等等。
这一范式的特点是什么?
我们在这个范例中所做的是以一种更接近现实的方式进行编程,我们根据类、对象、方法、属性等等进行编程,特别是集成了抽象、封装、模块
化、隐私、多态、继承等术语。
基于类和基于原型的语言都是面向对象程序设计语言的范式,经典的C#与JAVA就是基于类面向对象的,JavaScript面向对象是基于原型的。
在 ES5中,我们可以使用工厂模式进行下一个示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| console.log('*** PERSON ***'); function Person (name) { this.name = name; }
Person.prototype = { eyes: 2, month: 1, sleep: function () { return 'zzz'; } };
const p1 = new Person('OldWang');
console.log( `name: ${p1.name}`, `eyes: ${p1.eyes}`, `month: ${p1.month}`, p1.sleep() ); console.log('*** EMPLOYEE ***')
function Employee (name, salary) { this.name = name; this.salary = salary; }
Employee.prototype = Object.create(Person.prototype); Employee.prototype.constructor = Employee;
const em1 = new Employee('tom', 3000);
console.log( `name: ${em1.name}`, `salary: ${em1.salary} RMB`, `eyes: ${em1.eyes}`, `month: ${em1.month}`, em1.sleep() );
|
现在,在ES6
中,我们可以用一种简单的方式来完成所有这些操作,但是我们必须记住,这只是语法糖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| class Person { constructor (name) { this.name = name; this.eyes = 2; this.month = 1; } sleep () { return 'zzz'; } }
class Employee extends Person { constructor (name, salary) { super(name); this.salary = salary; } }
const p1 = new Person('Nick');
console.log( `name: ${p1.name}`, `eyes: ${p1.eyes}`, `month: ${p1.month}`, p1.sleep() );
const em1 = new Employee('John', 3000);
console.log( `name: ${em1.name}`, `salary: ${em1.salary} USD`, `eyes: ${em1.eyes}`, `month: ${em1.month}`, em1.sleep() );
|
在这种情况下,使用 extends
关键字,我们只需说: ‘好吧,我想继承 Person 类的产品’。 但在幕后,这与我们在 es5示例中使用原型所做的是一样的。
静态方法
1 2 3 4 5 6 7
| class Dog { static whatIs() { return '一种可爱的动物'; } }
console.log( Dog.whatIs() );
|
私有方法
在 JavaScript 中,我们没有像 Java
和 C#
那样的 private
关键字,重要的是在 JavaScript 中,我们有一个用于 private
值的约定, 这个约定是在单词之前使用一个下划线 _
让我展示给你看:
1 2 3 4 5 6 7 8 9 10
| class Person { constructor (name, phone) { this.name = name; this._phone = phone; } } const p1 = new Person('John', 544342212);
console.log(p1._phone);
|
ES6中,我们有一个对象调用WeakMap
,我们可以用他创建私有属性,让我们看看:
1 2 3 4 5 6 7 8 9 10
| const secret = new WeakMap(); class Person { constructor (name, phone) { this.name = name; secret.set(this, {_phonenumber: phone}); } } const p1 = new Person('John', 544342212);
console.log(p1._phonenumber);
|
GET&SET
当我们有私有属性时,通常会创建一个返回私有值的公有方法,因此我们必须返回一个值并设置一个新值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const secret = new WeakMap(); class Person { constructor (name, phone) { this.name = name; secret.set(this, {_phonenumber: phone}); } get phoneNumber() { return secret.get(this)._phonenumber; } set phoneNumber(newNumber) { secret.get(this)._phonenumber = newNumber; } }
const p1 = new Person('John', 544342212);
console.log(p1.phoneNumber); p1.phoneNumber = 432232323; console.log(p1.phoneNumber);
|
多态
多态(Polymorphism)是指由继承而产生的相关的不同的类,其对象对同一消息会做出不同的响应。
我们先用ES5原型来实现多态:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| var makeSound = function(animal) { animal.sound(); }
var Duck = function(){} Dog.prototype.sound = function() { console.log('汪汪汪') } var Chiken = function() {}; Chiken.prototype.sound = function() { console.log('咯咯咯') }
makeSound(new Dog()); makeSound(new Chicken());
|
接下来用Class
来实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Animal{ cry(){}; }
class Dog extends Animal{ static cry(){ return '汪汪汪'; } }
class Chiken extends Animal{ static cry(){ return '咯咯咯'; } } console.log(Dog.cry()); console.log(Chiken.cry());
|
资源
面向对象程序设计
Thanks for watching!😉