什么是面向对象(oop)?
概念
面向对象(Object Oriented,OO)是软件开发方法.使用对象时,只关注对象提供的功能,不关注其内部细节。比如电脑——有鼠标、键盘,我们只需要知道怎么使用鼠标,敲打键盘即可,不必知道为何点击鼠标可以选中、敲打键盘是如何输入文字以及屏幕是如何显示文字的。总之我们没必要知道其具体工作细节,只需知道如何使用其提供的功能即可,这就是面向对象。。
面向对象就是一种新的编程模式。
面向对象在其它编程语言中普遍使用,Java,PHP,Python,C
什么是对象?
什么是收音机,对象是一个整体,对外提供一些操作。
什么是面向对象开发?
就是在使用对象时,只关注对象提供的功能,不关注其内部细节。
比如,每次使用封装好的运动框架
面向对象的特点
封装:
对于一些功能相同或者相似的代码,我们可以放到一个函数中去,多次用到此功能时,我们只需要调用即可,无需多次重写
继承:
子类可以继承父类的属性和方法
多态:(重载和重写)
重载:严格意义上说js中没有重载的功能,不过我们可以通过判断函数的参数的不同来实现不同的功能来模拟重载。
重写:子类可以改写父类的属性和方法
对象的组成
方法(有归属)----函数(自由的)
属性(有归属)----变量(自由的)
案例:一个人拥有特征和动作
var person = {
name: ['Bob', 'Smith'],
age: 32,
gender: 'male',
interests: ['music', 'skiing'],
bio: function () {
alert(this.name[0] + ' ' + this.name[1]+ ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1]+ '.');
},
greeting: function () {
alert('Hi! I\'m ' + this.name[0]+ '.');
}
作为一个人,具有姓名,年龄,性别,爱好等等属性,而且有各种方法,会打招呼(greeting()),会做饭。
面向对象和面向过程的区别
面向过程就是分析出解决问题需要的步骤,然后用函数把这些步骤一个个实现,使用的时候依次调用,面向过程的核心是过程。
面向对象就是把构成问题的事物分解成一个个对象,建立对象不是为了实现一个步骤,而是为了描述某个事物在解决问题中的行为,面向对象的核心是对象
面向对象是什么?其实本质上就是一个“模板”,就像做月饼一样,我们需要一个月饼模子,而使用月饼模子做出的月饼基本一致
JS中常见的几种模式
单例模式
var xiaoming = {
num:1,
getNum:function(){
return 1;
}
}
var xiaohua = {
num:2,
getNum: function(){
return 2;
}
}
我们把描述同一个事物的方法或者属性放到同一个对象里,不同事物之间的方法或者属性名相同相互也不会发生冲突。命名空间是不一样的.
缺点: 单例模式让每个对象有了自己独立的命名空间,但是并不能批量生产的问题,每一个新的对象都要重新写一份一模一样的代码
工厂模式
工厂模式其实就是把需要一个个的编写的对象,放在一个函数中统一的进行创建,说白了就是普通函数的封装。
工厂模式总共3步骤:
1)引进原材料 --- 创建一个空对象
2)加工原材料 --- 加工对象:给对象添加属性和方法;
3)输出产品 --- 返回对象:return 对象;
function CreatePerson(name,age){
var obj={};//1.创建一个空对象
//2.加工对象
obj.name=name;
obj.age=age;
obj.showName=function(){
console.log('我的名字是:'+this.name)
};
return obj;//3.输出对象;
}
var person1 = CreatePerson('小明',23)
var person2 = CreatePerson('小华',23)
person1.showName(); //我的名字是:小明
person2.showName(); //我的名字是:小华
既然叫工厂模式,它就和我们周围的工厂一样,我们只需要把原材料放进去,就能得到我们需要的产品了。
工厂模式也解决了单例模式的批量生产的问题,避免了单例模式中的大量冗余代码,进行系统的封装,提高代码的重复利用
构造函数模式(内置工厂模式)
-
可以创建一个自定义的类,并且可以new出实例
-
构造函数做的就是类和实例打交道
//构造函数:首字母大写(约定俗成); function CreatePerson(name,age){ //创建一个自定义的类 //构造函数中的this,都是new出来的实例 //构造函数中存放的都是私有的属性和方法; this.name=name; this.age=age; this.showName=function(){ console.log('我的名字是:'+this.name) } } //实例1 var person1 = new CreatePerson('小明',25) //实例2 var person2 = new CreatePerson('小华',24)
原型模式
function CreatePerson(name,age){ this.name=name; this.age=age; } // 我们把公有的方法放到函数的原型链上 CreatePerson.prototype.showName = function(){ console.log('我的名字是:'+this.name) } var person1 = new CreatePerson('小明',25) var person2 = new CreatePerson('小华',24) person1.showName() //小明 1)每个函数数据类型(普通函数,类)上,都有一个属性,叫prototype。 2)prototype这个对象上,天生自带一个属性,叫constructor:指向当前这个类; 3)每个对象数据类型(普通对象,prototype,实例)上都有一个属性, 叫做__proto__:指向当前实例所属类的原型;
构造函数(ES5)
构造函数和对象的关系
我们在javaScript里用构造函数来实现面向对象编程
需要使用构造函数来new出对象,然后进行编程
例1:定义一个人的构造函数,然后传入参数且实例化
function Person(first, last, age, gender,interests) {
this.name = {
first,
last
};
this.age = age;
this.gender = gender;`
this.interests = interests;
}
//我们首先定义了一个类别为人的构造函数,当我们想要描述一个人的时候,给他传进去参数就可以了,比如
var person1=new Person('Chris','Martin',32,'male',['music','guitar']);
//我们首先定义了Christ Martin,
//再定义一个人
var person2=new Person('Gwyneth','Paltrow','35','female',['ironman','movie'])
多学一招:
1 为了区别普通函数,构造函数的名字一般都大写,
2 必须实例化之后,进行调用
原型对象
1 实例对象通过构造函数进行创建,原型对象是有了构造函数就会产生的。
2 构造函数中的属性通过结构(dir)查看时不在构造函数中而是在实例对象中的,构造函数里有个原型对象(prototype),原型对象里有个构造器(constructor),指向构造函数。
原型对象的作用
prototype
属性的作用就是让该函数所实例化的对象们都可以找到公用的属性和方法.
1: 对比两个创建的函数.
// 在对象中,两个新创建的函数,是不相等的:
var obj1 = {
fn:function(){
alert(1);
}
}
var obj2 = {
fn:function(){
alert(1);
}
}
console.log(obj1.fn == obj2.fn); //false
2 用构造函数创建new 两个对象也是不相等的
function Fn(name){
this.name = name;
this.show = function(){
alert(this.name);
}
}
var obj1 = new Fn("AAA");
var obj2 = new Fn("BBB");
console.log(obj1.fn==obj2.fn); //false
console.log(obj1); /
console.log(obj2);
// 总结:1 obj1与obj2多包含了共同的方法show,造成了冗余,浪费了内存
// 2 此时的protype 也指向了原型
问题:因为构造函数内包含的东西,比较多.可以看出构造函数的多次创建会产生多个同名函数,造成冗余太多。
3 解决:先定义简答的构造函数,实例化对象之后再用prototype进行添加
function Fn(){}
console.log(Fn.prototype);
//constructor表示当前的函数属于谁
//__proto__ == [[prototype]],书面用语,表示原型指针
var fn1 = new Object();
var fn2 = new Object();
Object.prototype.show = function(){
alert(1);
}
console.log(fn1.show==fn2.show); //ture
proto的解释
这里我们仅留下 __proto__ 属性,它是对象所独有的,可以看到__proto__属性都是由一个对象指向一个对象,即指向它们的原型对象(也可以理解为父对象),那么这个属性的作用是什么呢?它的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(可以理解为父对象)里找,如果父对象也不存在这个属性,则继续往父对象的__proto__属性所指向的那个对象(可以理解为爷爷对象)里找,如果还没找到,则继续往上找…直到原型链顶端null(可以理解为原始人。。。),此时若还没找到,则返回undefined(可以理解为,再往上就已经不是“人”的范畴了,找不到了,到此结束),由以上这种通过__proto__属性来连接对象直到null的一条链即为我们所谓的原型链。
constructor
constructor属性也是对象才拥有的,它是从一个对象指向一个函数,含义就是指向该对象的构造函数,每个对象都有构造函数
使用Json创建对象
key/value的形式,直接使用对象名调用即可
例:创建构造一个obj,保存人的姓名,年龄,爱好,并且输出个人信息
var obj = {
name:"admin",
age:23,
like:"LOL",
show:function(){
alert("我叫"+obj.name+",今年"+obj.age+"岁,喜欢"+obj.like)
}
}
obj.show()
1.类的概念
类是现实世界在计算机中的反映,它将数据和对这些数据的操作封装在一起(并没有开空间),主要是为了更好的实现面向对象编程,是ES6中新增的语法.
2.类和对象
对象就是通过new 类之后得到的,可以调用类中的方法和属性
例1:声明一个person类,包括属性和方法且输出
class Person{//定义了一个名字为Person的类
this.name = 'zs';//this代表的是实例对象
this.age=16;
say(){//这是一个类的方法,注意千万不要加上function
return "我的名字叫" + this.name+"今年"+this.age+"岁了";
}
}
var obj=new Person("laotie",88);
console.log(obj.say());//我的名字叫laotie今年88岁了
脚下留心
1.在类中声明方法的时候,千万不要给该方法加上function关键字
2.方法之间不要用逗号分隔,否则会报错
ES6中的类就是构造函数的另一种写法
console.log(typeof Person);//function
console.log(Person===Person.prototype.constructor);//true
例2:通过prototype属性添加新的方法
Person.prototype.say=function(){//定义与类中相同名字的方法。成功实现了覆盖!
return "我是来证明的,你叫" + this.name+"今年"+this.age+"岁了";
}
var obj=new Person("laotie",88);
console.log(obj.say());//我是来证明的,你叫laotie今年88岁了
例3:constructor是默认构造方法
class Box{
constructor(){
console.log("啦啦啦,今天天气好晴朗");//当实例化对象时该行代码会执行。
}
}
var obj=new Box();
static 静态类
static
关键字用来定义一个类的一个静态方法。调用静态方法不需要实例化该类,但不能通过一个类实例调用静态方法。静态方法通常用于为一个应用程序创建工具函数
例1:创建一个静态方法,进行调用
class Point {
constructor(x, y) {
}
static distance(a, b) {
return a+b;
}
}
console.log(Point.distance(1,2));
extends super的使用
3.JSON字符串和对象直接的转换
JSON字符串格式
var str = '{ "name": "programer", "age": "18" }';
JSON字符串转换为JSON对象
var obj = str.parseJSON();//将JSON字符串转换为JSON对象
var obj = JSON.parse(str);// 将字符串转换为JSON对象
将JSON对象转化为JSON字符串
var str = JSON.stringify(obj);
var str = obj.toJSONString();