面向对象编程思想和构造函数创建对象
Posted www11
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象编程思想和构造函数创建对象相关的知识,希望对你有一定的参考价值。
1、什么是面向对象
所谓的面向对象,是一种编程思想,编程思路,代码的书写格式。之前为了简化代码,我们是将程序封装为函数的形式来调用
函数会有一些小问题:
函数内部定义的局部作用域变量,函数外部无法直接调用
函数调用使用时,会占用大量的系统内存,容易造成数据溢出数据泄露,容易被黑客攻击
函数一般只是封装一些模块化的功能
复杂程序的封装会,封装成其他形式,使用面向对象的方式来封装程序。
为什么要面向对象,不是面向字符串等
对象的优点
1,对象中,可以定义并且存储多个数据单元以及所有javascript支持的数据类型
2,对象中,调用具体数据很方便,调用数据时,不用考虑数据的顺序,只要键名/属性 输入正确就可以了
3,对象中,可以定义函数,还可以通过函数的this,方便的调用对象本身的数据。调用对象的数据,不用管对象名称 是什么,只要通过this,就可以指向这个对象,
2、面向对象的基本思路
基本思路就是,创建一个对象,给这个对象,添加上属性和属性值,还有函数等方法,之后通过操作这个对象,来完成需要的效果
// 先通过一个函数的方法,来创建对象 function createObj(){ // 创建对象 const obj = {}; // 给对象添加属性和属性值 obj.name = ‘张三‘; obj.age = 18; obj.addr = ‘北京‘; obj.sex = ‘男‘; // 给对象添加方法 obj.funNameAge = function(){ console.log(this.name , this.age); } obj.funNameAddr = function(){ console.log(this.name , this.addr); } obj.funSexAge = function(){ console.log(this.sex , this.age); } obj.funAll = function(){ console.log(this.name, this.sex , this.age, this.addr); } // 返回这个创建好的对象 return obj; } // 调用函数,函数创建对象,并且作为返回值 // 变量中存储的就是函数创建的对象 const obj = createObj(); // 可以通过调用obj中存储的对方的方法,来实现功能 obj.funAll();
3、工厂模式
工厂模式
所谓的工厂模式,是一种书写函数的语法形式,语法规范
就向工厂中的流水线一样,按照步骤来执行需要的操作
步骤1,创建对象
步骤2,给对象定义属性和属性值
步骤3,给对象添加方法
步骤4,定义对象为返回值
标准的工厂模式,会有对应的参数
function createDumpling(pi,mian,xian,tioliao){ // 创建包饺子对象 const dumpling = {}; // 给包饺子对象,添加属性 dumpling.pi = pi; dumpling.xian = xian; dumpling.mian = mian; dumpling.tiaoliao = tiaoliao; // 给包饺子对象,添加方法 // 和面 dumpling.huomian = function(){ console.log(this.mian); } // 和饺子馅 dumpling.huoxian = function(){ console.log(this.xian); } // 包饺子 dumpling.bao = function(){ console.log(this.xian,this.pi,this,mian); } // 煮饺子 dumpling.zhu = function(){ console.log(‘煮饺子了,等着吃吧‘); } // 返回包饺子对象 return dumpling; } // 要开始包饺子 // 创建一个执行包饺子功能的对象,并且输入参数 const baojiaozi1 = createDumpling(‘薄皮‘ , ‘白面粉‘ , ‘猪肉大葱‘); const baojiaozi2 = createDumpling(‘厚皮‘ , ‘玉米面‘ , ‘鱼香肉丝‘); console.log(baojiaozi1); // 可以调用任意的封装的方法 baojiaozi1.huoxian(); // 调用和饺子馅方法 baojiaozi1.huomian(); // 调用和面方法
根据工厂模式可以推断:
面向对象编程的优点
(1)优点与函数的优点类似
高内聚 低耦合
高内聚 : 将所有需要的程序,都定义封装在对象内
对象中存储所有需要的属性,所有需要的方法
低耦合 : 尽量减少特殊程序的执行
(2)面向对象编程的特点
抽象 --- 通过描述 对象 共有的特点(属性和属性值) , 来形容一个对象
这个对象不是一个非常具体事例的内容,是一个抽象化的实例
制作饺子,制作包子,制作馅饼,制作馅窝头...
有皮,有汁,味甜 --- 西瓜 , 橘子 , 桃 , 爆浆蛋糕 , 夹心糖果 ...
四条腿的,有一个面的 --- 桌子 , 凳子 , 床 ...
封装 --- 将所有的程序,都定义在一个对象中
4、自定义构造函数来创建对象
创建对象可以使用字面量来创建对象,也可以使用构造函数来创建对象。所谓的构造函数,实际也是一种函数,是专门用于生成定义对象的,通过构造函数生成的对象,称为实例化对象。
5、解决构造函数中的方法重复生成问题
构造函数分为两种,一种是JavaScript程序定义好的构造函数,称为 内置构造函数
一种是程序员自己定义的构造函数,称为 自定义构造函数
构造函数和普通函数的区别
1,构造函数一定要和 关键词 new 一起使用
new 关键词具有特殊的功能,
会自动的给 构造函数中 定义一个对象,并且返回这个对象
我们只要对这个对象设定属性,设定方法就可以了
2,构造函数为了和其他函数区别
语法规范规定,构造函数,函数名称,第一个字母必须大写,使用大驼峰命名法
3,构造函数,给对象定义属性和方法的语法,与一般函数不同
实例化对象和普通的对象,没有任何的区别,只是建立方式不同而已
function CrtObj(name,age,sex,addr){ // 在构造函数中,使用this,来指代对象 // 这个对象,就是我们使用构造函数,生成的实例化对象 // 定义属性 // 给实例化对象,添加name属性,属性值是输入的name参数 this.name = name; this.age = age; this.sex = sex; this.addr = addr; // 定义方法 this.funAll = function(){ console.log(this.name,this.age,this.sex,this.addr ) } this.funNameAge = function(){ console.log(this.name,this.age) } this.funSexAddr = function(){ console.log(this.sex,this.addr ) } } // 通过自定义构造函数来生对象,实例化对象 // 调用执行构造函数时,都必须要和new 关键词一起使用 const obj1 = new CrtObj(‘张三‘,18,‘男‘,‘北京‘); console.log(obj1); // 调用 对象/实例化对象 中的方法 obj1.funAll(); obj1.funNameAge(); obj1.funSexAddr();
new 的作用
(1)在构造函数中,自行创建一个对象,并且返回这个对象
(2)因为new 关键词,创建了对象,此时,构造函数中的this,才会指向这个对象,也就是将来生成的实例化对象
(3)所有的构造函数中,this的指向,都是将来通过这个构造函数生成的实例化对象
每个实例化对象中,都有属性和方法,通过同一个构造函数,生成的实例化对象属性相同,属性值可能不同。定义的方法的程序,是相同的,但是,如果做一个比较判断,结果是 false。 表示,不同的实例化对象中,定义的是不同的方法/函数,不同的方法和函数,会占用过多的内存空间。要想办法,让使用同一个构造函数,生成的实例化对象,都是相同的方法。
解决的方式
将构造函数需要定义给实例化对象的方法,定义在函数的 prototype 属性中
function CrtObj2(name, age, sex, addr) { // 定义属性 this.name = name; this.age = age; this.sex = sex; this.addr = addr; } // 在构造函数的 prototype 属性中,来定义实例化对象的方法 CrtObj2.prototype.fun = function(){ console.log(this.name, this.age, this.sex, this.addr); } const obj4 = new CrtObj2(‘张三‘,18,‘男‘,‘北京‘); const obj5 = new CrtObj2(‘李四‘,19,‘女‘,‘上海‘);
console.log(obj4);
console.log(obj5);
obj4.fun();
console.log( obj4.fun === obj5.fun );
所有通过这个构造函数生成的实例化对象,实际上,本身都没有定义方法和函数。使用时,都是调用生成实例化对象的构造函数,本身prototype中定义的方法,就不会重复生成函数,占用内存空间。
这里,就使用到了原型对象、原型属性、原型链:
1,原型对象
每一个函数,天生都有一个 prototype 属性,称为原型对象
是一个专门用来存储数据,函数等内容的空间
2,原型属性
每一个对象,天生都有一个 __proto__ 属性,称为原型属性
实例化对象的原型属性,指向的创建实例化对象的构造函数的 prototype
函数,数组,等,JavaScript中的数据类型
实际存储的形式都是一个对象,都会有 __proto__ 属性
在JavaScript中,可以用对象的形式存储任何数据类型
3,原型链
所谓的原型链,就是所有相互关联的变量,使用 __proto__ 属性串联起来
调用数据数据时,会通过 __proto__ 将所有相互关联的 变量 串联
只要有一个变量中 有相应的属性,就会调用成功
6、ES6中新增的构造函数的写法
ES6中,新增语法形式 class 类,是一种新的定义构造函数的语法,作用和原理与ES5语法完全相同,只是语法格式和书写方式不同。
class Fun1{ constructor(name,age){ this.name = name; this.age = age; } f2(){ console.log(this.name , this.age); } } const obj1 = new Fun1(‘张三‘,18);
它的方法是写在函数内部的,虽然书写格式不同,方法也是定义在构造函数prototype属性中的。但是这样写起来更简便,代码的可读性更高
以上是关于面向对象编程思想和构造函数创建对象的主要内容,如果未能解决你的问题,请参考以下文章