JS面向对象
JavaScript面向对象概述
1.1 什么是对象?
Everything is object (万物皆对象)
可以从下面两个方面来理解
1.对象是对单个事物的抽象
2.对象是一个容器,封装了属性(property)和方法(method)
1.2 什么是面向对象?
面向对象只是过程式代码的一种高度封装,目的在于提高代码的开发效率和可维护性
1.2.1面向对象与面向过程
1.面向过程就是亲力亲为
2.面向对象就是将执行者转变为指挥者
3.面向对象是对面向过程的封装
对象定义的两种方式
2.1字面量的方式进行定义
var obj = {
name: "Tom ",
sex: " man",
age:19,
run:function(){
console.log("一天跑一公里");
}
}
2.2使用 new Object()进行定义
var obj = new Object();
obj.name = "Tom ";
obj.sex = " man";
obj.age = 19;
obj.run = function(){
console.log("一天跑一公里");
}
类和对象
3.1什么是类(class)?
具有相同特性(数据元素)和行为(功能)的对象的抽象就是类,因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象,类实际上就是一种数据类型。类具有属性,它是对象状态的抽象,用数据结构来描述类的属性。类具有操作,它是对象行为的抽象,用操作名和实现该操作的方法来描述。
3.2类和对象的区别
类(Class)是一个抽象的概念,对象则是类的具体实例
3.3类和对象的关系
类实例化的结果就是对象,而对象的抽象就是类,类描述了一组有相同特性(属性)和相同行为的对象
class person{ }//这个是类
$obj = new person();//类的实例化就是对象
创建对象的三种方式
4.1工厂模式
使用简单的函数创建对象,为对象添加属性和方法,然后返回对象
// Class 模板
function Person(name,sex,age){
var obj = {};
obj.name = name;
obj.sex = sex;
obj.age = age;
obj.run = function(){
console.log("每天坚持跑步");
}
return obj;
}
// 实例化
var person1 = Person("Tom","sex",19);
//操作
person1.run(); // 输出结果:每天坚持跑步
4.1.1工厂模式的优缺点
优点:
1.在工厂模式中,用户只需要知道所要生产的具体东西,无需关心具体的创建过程,甚至不需要具体产品类的类名
2.在系统增加新的产品时,我们只需要添加一个具体产品类和对应的实现工厂,无需对原工厂进行任何修改,很好的符合了“开闭原则”
缺点:每次增加一个新产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定的程度上增加了系统的复杂度,同时也增加了系统具体类的依赖
4.2构造函数模式
创建自定义引用类型,可以像创建内置对象实例一样使用new操作符
缺点:构造函数的每个成员无法复用,每次创建出的对象都只是私有变量和私有方法,不能实现共用
//构造函数(这里就创建了一个Class模板)
function Person(name,sex,age){
this.name = name;
this.sex = sex;
this.age = age;
this.run = function(){
console.log("每天坚持跑步");
}
}
// 实例化 ( new Object())
var person1 = new Person("Tom","man",19);
//操作
person1.run();// 每天坚持跑步
4.2.1构造函数的改进
// 构造全局的对象
var action = {
run:function(){
console.log("每天坚持跑步");
}
}
//构造函数
funcction(name,sex,age){
this.name = name;
this.sex = sex;
this.age = age;
this.run = action.run;
}
//实例化
var person1 = new Person("Tom","man",19);
person1.run();
4.3原型模式
使用构造函数的prototype属性来指定共享的属性和方法,即使用构造函数定义实例属性,使用原型定义共享的属性和方法
//构造函数
function Person(name,sex,age){
this.name = name;
this.sex = sex;
this.age = age;
}
//使用原型对象 Object.prototype
Person.prototype.run = function() {
console.log("每天坚持跑步");
}
//实例化
var person1 = new Person("Tom","man",19);
person1.run();// 每天坚持跑步
构造函数,原型对象,实例化对象的关系
proto: 对象的原型。所有对象都有(包括函数)
prototype:函数的原型对象。只有函数(准确来说是构造函数)才有
constructor:对象上的一个属性,默认指向这个原型的构造函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W6lTLyPQ-1594203192274)(C:\Users\Administrator\Desktop\01.webp)]
this指向
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向的是谁
5.1 案例1
function show(){
var user = "Tom";
console.log(this.user);//undefined
console.log(this);//window
}
show();
this最终指向的是调用它的对象,这里的函数show()实际是被Window对象所调用出来的
function show(){
var user = "Tom";
console.log(this.user);//undefined
console.log(this);//window
}
window.show();
5.2 案例2
var show = {
user:"Tom",
fn:function(){
console.log(this.user);//Tom
}
}
show.fn();
这里this指向的是对象show,谁调用就指向谁
5.3构造函数版this
function Fn(){
this.user = "Tom";
}
var a = new Fn();
console.log(a.user); //Tom
这里this指向对象a,因为new关键字可以改变this的指向
当this碰到return:
function Fn(){
this.user = "Tom";
return {};
}
var a = new Fn();
console.log(a.user);//undefined
function Fn(){
this.user = "Tom";
return funciton(){};
}
var a = new Fn();
console.log(a.user);//undefined
function Fn(){
this.user = "Tom";
return 1;
}
var a = new Fn();
console.log(a.user);// Tom
function Fn(){
this.user = "Tom";
return undefined;
}
var a = new Fn();
console.log(a.user);//Tom
如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例
function Fn(){
this.user = "Tom";
return null;
}
var a = new Fn();
console.log(a.user);//Tom
虽然null也是对象,但是在这里this还是指向那个函数的实例,因为null比较特殊