这是我参与8月更文挑战的第13天,活动详情查看:8月更文挑战
前言
相信大家都听过一句话啊,万物皆对象!
人 , 车 ,猫
人 : 眼睛 头发 会敲代码
车 : 品牌 价格
猫 : 颜色 会抓老鼠
以上都是数据 都记录在对象中
var person = { 眼睛 ,头发 ,会敲代码 }
那到底什么是对象呢?我们先来简单的回顾一哈。
对象的概念: 对象是一个包含相关数据和方法的集合(通常由一些变量和函数组成,我们称之为对象里面的属性和方法),把很多零散的东西,,封装成为一个整体。
例如小明,他有升高,体重,年龄,性别等等;他还会干嘛啊,会吃饭,跑步,睡觉。那换成对象怎么表示呢?我们可以这样写
var person = {
// 属性
height: '180cm',
weight: '70kg',
age: 18,
sex: 'man',
// 行为
eat: function () {
console.log('小明会吃饭!');
},
run: function () {
console.log('小明会跑步!');
},
sleep: function () {
console.log('小明会睡觉!');
}
}
那我们怎么样才能
访问对象的属性和方法呢? 两种方法:
- 点表示法
person.age // 18
- 括号表示法(是中括号[])
person['age'] // 18
括号表示法一个有用的地方是它不仅可以动态的去
设置对象成员的值,还可以动态的去设置成员的名字。
比如说,我们想让用户能够在他们的数据里存储自己定义的值类型,通过两个input框来输入成员的名字和值,通过以下代码获取用户输入的值:
var myDataName = nameInput.value
var myDataValue = nameValue.value
我们可以这样把这个新的成员的名字和值加到person对象里:
person[myDataName] = myDataValue
为了测试这个功能,尝试在你的代码里添加以下几行,就在person对象的右花括号的下面:
var myDataName = 'height'
var myDataValue = '1.75m'
person[myDataName] = myDataValue
现在,保存并刷新,在输入框里输入以下代码:
person.height
这是使用点表示法无法做到的,点表示法只能接受字面量的成员的名字,不接受变量作为名字。
一、面向对象与面向过程
都是一种解决问题的思路(思想)
面向过程:在解决问题的时候,关注的是解决问题需要的一个接着一个的过程,比较直观的通过代码实现某个业务。(代码是比较清晰的)
面向对象:在解决问题的时候,关注的是解决问题所需要的对象(面向对象本身是对面向过程的封装,代码难点是理解this)
问:面向对象编程最重要的什么?
答:找到对象, 确定对象属性和行为。
举个例子啊:就是你做好饭然后就洗碗,是不是先得做饭然后再干嘛干嘛是吧。这里我们贴图方便理解一点。
面向过程:
面向对象:
那我们可以发现啊,面向过程就是有个先后顺序,一步接着一步。而面向对象呢,是把某一部分集中到一个对象中,然后再把属于当前版块的在一起进行操作。
那我们总结一下,面向对象的好处是什么?
- 更方便
- 复用性会更好
- 高内聚和低耦合
- 冗余(重复的东西)-->封装(提取相同的部分作为函数体,抽取不同的部分作为参数)
以及面向对象的三大特点
- 封装 : 对整体业务进行客观的描述 ,然后把相关数据记录在对象当中
- 继承 : 一个对象可以有子类,子类可继承父类的属性和方法
- 多态 : 对象可以有多个功能,多个方法, 一个方法可以有多种表现形式
二、面向对象-创建对象的方式
1. 字面量的方式创建对象
使用字面量的方式来创建对象差不多,都存在以下问题:
- 创建的对象无法复用,
复用性差 - 如果需要创建多个同类型的对象,如(书籍)则需要写大量
重复的代码,代码的冗余度高
var person = {
// 属性
height: '180cm',
weight: '70kg',
age: 18,
sex: 'man',
// 行为
eat: function () {
console.log('小明会吃饭!');
},
run: function () {
console.log('小明会跑步!');
},
sleep: function () {
console.log('小明会睡觉!');
}
}
2. 内置构造函数的方式来创建对象
使用内置构造函数的方式来创建对象差不多,都存在以下问题:
- 创建的对象无法复用,
复用性差 - 如果需要创建多个同类型的对象,如(书籍)则需要写大量
重复的代码,代码的冗余度高
其实啊,就是使用
new Object说到这又想起了一个经典面试题:
new 关键字做了什么?。相信大家都不陌生。
//例如: 创建一个人对象
let person = new Object();
//person对象身上的属性
person.uname = '张三';
//person对象身上方法
person.eat = function () {
console.log('我叫张三,我会吃饭。');
}
3. 简单工厂函数的方式来创建对象
我们可以这样简单的理解一下:
简单工厂模式:工厂里面有一些产品的模板, 只需要, 给工厂提供原材料; 工厂按照固定的加工方式, 就可以返回给外界同一类型的产品
那么所存在的问题是什么呢?
答:使用工厂方法创建的对象,使用构造函数都是object,所以创建的对象都是object这个类型,导致无法判定类型
function creatPerson(name, age, sex) {
// 创建一个新的对象
var obj = new Object();
// 向对象里添加属性
obj.name = name;
obj.age = age;
obj.sex = sex;
obj.say = function () {
console.log(this.name);
};
// 将新的对象返回
return obj;
}
var person1 = creatPerson('Jack', 19, 'man');
var person2 = creatPerson('Rose', 29, 'female');
var person3 = creatPerson('Tom', 13, 'man');
4. 自定义构造函数的方式来创建对象
我们先简单写个代码,然后再分析分析构造函数和工厂函数的区别,构造函数的执行过程以及它的返回值。
function Person(name, age) {
// 隐式操作:把new新创建出来的对象赋值给this
this.name = name;
this.age = age;
this.sayHello = function () {
console.log("Hello World");
}
}
var p = new Person('Jack', 20); //new Object(); 如果构造函数没有参数那么小括号是可以省略。
console.log('p ==> ', p);
p.sayHello();
4.1-自定义构造函数和简单工厂函数的对比
- ① 函数的
首字母大写(用于区别构造函数和普通函数) - ② 创建对象的过程是由
new关键字实现 - ③ 在构造函数内部会自动的创建新对象,并赋值给
this指针 - ④
自动返回(return)创建出来的对象 其实啊,这4个步骤就是new 关键字所做的事情。
4.2-构造函数的执行过程
- ① 使用new关键字创建对象 ---- 外界
- ② 把新创建出来的对象赋值给this
- ③ 在构造函数内部,使用this为新创建出来的对象设置
属性和方法 - ④ 默认返回新创建的对象(普通函数如果不显示的return则默认返回undefined)。
4.3-构造函数的返回值说明
-
01 如果在构造函数中
没有显示的return,则默认返回的是新创建出来的对象 -
02 如果在构造函数中
显示的return,则依照具体的情况处理- [01] return 的是对象,则直接返回该对象,取而代之本该默认返回的新对象
- [02] return 的是null或基本数据类型值,则返回新创建的对象
总结:
类型匹配才接受 --> 对象
三、面向对象-小案例(实现简易计算器)
- 计算器加减乘除运算
- 面向过程
- 使用对象形式
- 链式调用
1. 面向过程
就平常的操作,定义方法,调用方法。
<script>
// 定义加减乘除4个方法
function add(a, b) {
return a + b;
}
function reduce(a, b) {
return a - b;
}
function multiply(a, b) {
return a * b;
}
function divide(a, b) {
return a / b;
}
// (6 + 6) * 2 / 3 - 4
console.log(reduce(divide(multiply(add(6, 6), 2), 3), 4), '11111');
</script>
2. 使用对象形式
<script>
var Caculator = {
// 结果
result: 0,
// 行为
add: function (num) {
this.result += num;
},
reduce: function(num) {
this.result -= num;
},
multiply: function (num) {
this.result *= num;
},
divide: function (num) {
this.result /= num;
},
log: function () {
console.log(this.result,, '2222')
}
};
// (6 + 6) * 2 / 3 - 4
Caculator.add(6);
Caculator.add(6);
Caculator.multiply(2);
Caculator.divide(3);
Caculator.reduce(4);
Caculator.log();
</script>
3. 链式调用
<script>
var Caculator = {
// 结果
result: 0,
// 行为
add: function (num) {
this.result += num;
return this;
},
reduce: function(num) {
this.result -= num;
return this;
},
multiply: function (num) {
this.result *= num;
return this;
},
divide: function (num) {
this.result /= num;
return this;
},
log: function () {
console.log(this.result, '3333');
return this;
},
clean: function () {
this.result = 0;
return this;
}
};
// (6 + 6) * 2 / 3 - 4
Caculator.add(6).add(6).multiply(2).divide(3).reduce(4).log(); // 4
Caculator.clean().add(2).log(); // 2
</script>
四、结语
码字不易,如果觉得对你有帮助,觉得还不错的话,欢迎点赞收藏~
当然由于是个人整理,难免会出现纰漏,欢迎留言反馈。