面向对象
软件世界面向对象
面向过程编程思想
- 按步骤一步一步解决问题
面向对象编程思想:
找解决问题对象,调用功能解决问题, 如果对象不存在
=> 自己创建对象,封装功能,解决问题
创建对象
简单方式 new Object
let obj = new Object()
obj.name = 'rose'
obj.age = 18
字面量方式
let obj = {
name:'rose',
age:18
}
let obj1 = {
name:'jack',
age:20
}
let obj2 = {
name:'tom',
age : 21
}
工厂函数方法
根据传入属性值生成不同对象
缺点:不知道对象数据类型
// 工厂函数方式创建对象
// 根据传入属性值生成不同对象
function createObj(name,age){
let obj = {
name,
age
}
return obj
}
let obj1 = createObj('rose',18)
let obj2 = createObj('jack',20)
构造函数
创建对象 指定对象数据类型
语法
function Person(name,age){
//只定义对象属性和方法
this.name = name //this.name 给当前对象创建name属性,将形参name的值赋值给name属性
this.age = age
this.say = function(){
//this指向调用该方法的对象
console.log(this.name +'说话方式')
}
}
let p1 = new Person('jack',18) //new语句调用 创建对象属性为Person的对象
p1.say() // 说话方式
//对象的数据类型 => 构造函数名
- 构造函数名首字母大写,约定写成类型名
- 函数体中只定义属性和方法,不写其他形式代码
- 使用new语句调用 构造函数 创建对象
- 对象的数据类型 => 构造函数名 let arr = Array() //Array
事例
// 创建一个手机构造函数,使用new语句调用构造函数创建不同手机对象
function Phone(type, color) {
this.type = type // 类型
this.color = color // 颜色
this.call = function () {
console.log(this.type + '打电话')
}
this.sendMessage = function () {
console.log('发短信')
}
}
let phone1 = new Phone('iphone12', '白色')
phone1.call()
let phone2 = new Phone('saumang', '黑色')
phone2.call()
按钮事例
<button class="btn1">按钮1</button>
<button class="btn2">按钮2</button>
<div></div>
<script>
/*
面向对象和面向过程相互合作关系
封装对象过程,实质就是面向过程编程
*/
// 面向对象编程
// 找点击按钮改变区块颜色对象, 有调用功能解决问题
// 如果没有,创建点击按钮改变区块颜色对象
// 创建对象: 1. 构造函数, 2. 封装功能, 3. new 调用构造函数创造对象
// 记住: 节点定义为属性
function ChangeDivColor(btn,color) {
this.btn = document.querySelector(btn)
this.div = document.querySelector('div')
this.bindChangeColor = function () {
// 对象方法中this->当前对象
let _this = this
// 点击按钮改变区块颜色
this.btn.addEventListener('click', function () {
//↓如果为this.div 在事件处理函数中this->事件源->button
//button事件下没有div 所以那样写是错误的
_this.div.style.backgroundColor = color
// _this 是上面的对象方法中的this 指向当前对象 div在当前对象里
//除此外还可以用箭头函数,这样this就是指向上下文的当前对象
})
}
}
let c1 = new ChangeDivColor('.btn1','red')
c1.bindChangeColor()
let c2 = new ChangeDivColor('.btn2','green')
c2.bindChangeColor()
//面向过程编程
function test1() {
const btnEle = document.querySelector('.btn1')
const divEle = document.querySelector('div')
btnEle.addEventListener('click', function () {
divEle.style.backgroundColor = 'pink'
})
}
</script>
* {
padding: 0;
margin: 0;
}
div {
width: 200px;
height: 200px;
background-color: skyblue;
}
原型prototype
构造函数、实例、引用变量、对象名,对象概念区分
原型对象与实例对象和构造函数
原型对象
每个构造函数都有一个prototype属性指向它的原型对象
Person.prototype
// 构造函数
function Person(name, age) {
this.name = name
this.age = age
}
// Person.prototype原型对象
// 公共的say方法定义到Person构造函数的原型对象上
// 所有实例对象都可以访问原型对象上公共的属性和方法
Person.prototype.say = function () {
console.log('说话')
}
// 实例对象
let p1 = new Person('jack',18)
let p2 = new Person('rose',20)
p1.say()
p2.say()
console.dir(Person) //dir方法显示对象结构
console.dir(Person.prototype);
console.dir(p1)
console.dir(p2)
console.log( Person.prototype === p1.__proto__ );
面向对象编程思想
1. 找解决问题对象,如果对象存在调用其功能解决问题
2. 对象不存在,创建对象
3. 构造函数方式创建对象
- - 构造函数: 对象私有的属性和方法定义在构造函数中
- - 原型对象: 公共的属性和方法定义在原型对象上
原型对象属性方法简写
// 构造函数
function Person(name, age) {
this.name = name
this.age = age
}
// 原型对象
// Person.prototype.say = function () {
// console.log('说话 say')
// }
// Person.prototype.eat = function(){
// console.log('吃饭')
// }
// Person.prototype.type = '中国人'
Person.prototype = {
constructor: Person, // 手动添加constructor属性指向它的构造函数
type: '中国人',
say: function () {
console.log('说话 say')
},
eat: function () {
console.log('吃饭')
},
}
// 实例对象
let p1 = new Person('jack', 18)
p1.say()
p1.eat()
console.dir(Person.prototype)
内置对象的原型
- new Object() Object.prototype
- new Array() Array.prototype
- new Date() Date.prototype
原型方法中的this指向调用该方法的对象
console.dir(Array.prototype);
Array.prototype.sum = function(){
let s = 0
for(let i = 0; i < this.length; i++){
s += this[i]
}
return s
}
let arr = [10,20,30]
let s = arr.sum()
console.log('和是 ',s);
let arr1 = [1,2,3,4,5,6,7,8,9]
console.log( arr1.sum());
选项卡 面向对象
<div class="container" id="tab1">
<ul>
<li class="active">选项1</li>
<li>选项2</li>
<li>选项3</li>
</ul>
<ol>
<li class="on">区域1</li>
<li>区域2</li>
<li>区域3</li>
</ol>
</div>
<div class="container" id="tab2">
<ul>
<li class="active">NBA</li>
<li>娱乐</li>
<li>新闻</li>
</ul>
<ol>
<li class="on">NBA</li>
<li>娱乐</li>
<li>新闻</li>
</ol>
</div>
<script>
/*
面向对象实现选项卡效果
1. 找选项卡对象
2. 创建选项卡对象,封装其功能
构造函数: 私有属性和方法
原型对象: 公共属性和方法
*/
function Tab(id) {
this.rootEle = document.querySelector(id)
this.ulLis = this.rootEle.querySelectorAll('ul>li')
this.olLis = this.rootEle.querySelectorAll('ol>li')
}
// 切换选项和区域
Tab.prototype.onTab = function () {
let _this = this
// 1. 所有选项绑定点击事件
for (let i = 0; i < this.ulLis.length; i++) {
// 动态给选项绑定索引号
this.ulLis[i].setAttribute('index', i)
this.ulLis[i].addEventListener('click', function () {
// 清除所有选项选中效果
_this.clear()
// 给当前选项设置样式
this.className = 'active'
//获取当前选项索引号
let index = this.getAttribute('index')
_this.olLis[index].className = 'on'
})
}
}
// 清除所有选项选中效果
Tab.prototype.clear = function () {
for (let i = 0; i < this.ulLis.length; i++) {
this.ulLis[i].className = ''
this.olLis[i].className = ''
}
}
let t1 = new Tab('#tab1')
t1.onTab()
let t2 = new Tab('#tab2')
t2.onTab()
</script>
* {
padding: 0;
margin: 0;
}
ul,
li {
list-style: none;
}
.container {
width: 400px;
margin: 100px;
}
.container ul {
height: 50px;
background-color: skyblue;
text-align: center;
line-height: 50px;
display: flex;
}
.container ul li {
flex: 1;
border-right: 1px solid pink;
}
.container ul li:hover {
cursor: pointer;
}
.container ol {
position: relative;
height: 300px;
background-color: blueviolet;
}
.container ol li {
position: absolute;
top: 0;
left: 0;
text-align: center;
width: 400px;
line-height: 300px;
display: none;
}
.container ul .active {
background-color: rgb(223, 57, 16);
}
.container ol .on {
display: block;
}