一、面向对象编程(OOP)
全称为:Object Oriented Programming。
指的是使用对象时,只关注对象提供的功能,不关注其内部细节
是一种指导思想,其他后端语言一样的有。JS是一门真正的编程语言,也就是它是面向对象的。
二、学习OOP的目的
-
如何站在创建对象的角度来看待已有内置对象是如何创建的:
Math,String,Array,RegExp, Object, this,Number,…
可以扩展已有对象的方法和属性。
比如Array没有求和的方法或去重的方法
之前为了实现以上需求,自己写了一套方法(造轮子)
var arr=[2,43,5,65]; function sum(){ var num=0; for(var i=0;i < arr.length;i++){ num+=arr[i]; } return num; } sum();//和 var arr=[32,3,5,65]; //希望最好的方式,就是能提供一个现成的方法-比如就像那些数组自带的方法那样,push,pop arr.sum(12,3,4,5,6);//求和 arr.push(5)
-
我们学习了很多内置的对象,把他们都当做超级英雄,假设还想再创建几个超级英雄,比如孙悟空,姜子牙,那如何实现了,即自己造一个对象。就需要面向对象编程思想
三、面向对象的4个特征(具体内容)面试题
-
抽象
抓住核心问题,抽象重点在抽,提取的意思。
例子1:比如学生考试系统只关心学生的姓名,性别,成绩,而不关心他的体重、身高、爱好等
例子2:比如字符串对象,它提供的方法能满足所有需求吗?假设我要去掉字符串首尾的空格,能用内置的方法一步到位吗?很显然不行,因为它只关注了重点,不能直接解决的问题可以通过其他方式解决。
-
封装
把数据(变量或属性)和对数据的操作(方法或函数)存储在对象中的能力。
不考虑内部实现,只考虑功能使用。
-
继承
从已有对象上,继承出新的对象,一个类(或多个类)可以继承另一个类的属性和方法的能力。
例子:我们做按钮,按钮有长方形的、圆角的、圆形的,我们都可以通过在长方形的基础上,(如果在长方形基础上直接改就会影响所有的长方形按钮)加些特效让其变成圆形的或圆角的
-
多态
多种形态,相同的类拥有不同的方法的能力。
父类和子类具有相同的操作,但是功能可以不一样,不同的类有相同的方法和属性,但是实现的操作不太一样。
四、使用以上指导思想写一个面向对象的程序
-
使用工厂方式
使用Object来造一个全新的自定义对象,因为Object对象是一张白纸,”没有自己的方法和属性“。
//工厂: 原料---加工---出厂 function Sunwukong(name,age){ //超级英雄:孙悟空-这个就不是用面向对象的思想写的 //原料: 参数、和new var Sunwukong=new Object(); // 加工 // 给该对象添加方法和属性即可 Sunwukong.name=name; Sunwukong.age=age; Sunwukong.sayHello=function(){ alert("我是"+Sunwukong.name); } Sunwukong.sayAge=function(){ alert("我是"+Sunwukong.age); } // 出厂 return Sunwukong; } //自己写的对象,模板做好后就可以调用它批量生产了。 var s1=Sunwukong("齐天大圣",100); var s2=Sunwukong("弼马温",90);
问题:工厂方式创建的对象与内置对象相比,少了2样东西:
-
没有使用new关键字
//内置的有new关键字 var arr=new Array(1,2,3);
-
方法没有共用,最严重的问题。都是孙悟空,用的却是同名不同质的方法。
//比如上面的Sunwukong.sayAge的方法 console.log(s1.sayAge==s2.sayAge); //false
-
-
混合构造法(正确做法)
原则:
-
属性写在构造函数中
-
方法写在构造函数的原型属性prototype上。
示例代码:
//工厂: 原料---加工---出厂 // Sunwukong 叫构造函数 function Sunwukong(name,age){ //原料: 参数、和new // 给该对象添加方法和属性即可 // 对象的属性还是写在构造函数中 this.name=name; this.age=age; // 出厂 // return Sunwukong; } // 方法写在prototype上 Sunwukong.prototype.sayHello=function(){ console.log("我是"+this); console.log(this instanceof Sunwukong); } Sunwukong.prototype.sayAge=function(){ alert("我是"+this.age); } // this回顾: this指的是调用当前函数的那个对象,即该函数属于谁,this就指向谁。 //自己写的对象 var s1=new Sunwukong("齐天大圣",100); // this指的是即将被实例化出来的那个对象,即s1 var s2=new Sunwukong("弼马温",90); // 实例的方法sayAge就共用了 console.log(s1.sayAge==s2.sayAge); //true
-