js 中的面向对象
用对象的思想去写代码,就是面向对象
- 过程式编程
- 面向对象编程
面向对象编程(OOP)的特征
- 封装性
- 继承性
- 多态性
- 抽象性
对象的组成
- 属性
- 方法
工厂方式
- 封装函数
function createPerson(name) {
// 创建对象
let obj = new Object();
// 添加属性
obj.name = name;
obj.sayName = function () {
console.log(this.name);
};
// 返回对象
return obj;
}
let p1 = createPerson("张三");
let p2 = createPerson("李四");
p1.sayName(); // 张三
p2.sayName(); // 李四
当用 new 关键字创建对象的时候,会执行构造函数中的代码,这个 this 指向的是新创建的对象,所以可以给对象添加属性。
function Person(name) {
//隐式返回this,this指向新创建的对象
this.name = name;
this.sayName = function () {
console.log(this.name);
};
}
let p3 = new Person("张三");
let p4 = new Person("李四");
p3.sayName(); // 张三
p4.sayName(); // 李四
对象引用中的问题
- 浪费内存空间
console.log(p3.sayName === p4.sayName); // false
- js 中的赋值方式
- 按值传值
- 引用传值
原型
- 每个函数都有一个 prototype 属性,这个属性是一个对象,默认情况下它只包含一个不可枚举的属性 constructor,指向函数本身。
- 每个对象都有一个 proto 属性,这个属性指向创建该对象的函数的 prototype。
- 改写对象下面的公共方法
- 类似与 css 中的 class,js 中的 prototype
- 原型要写在构造函数下面
案例,面向对象的选项卡
window.onload = function () {
let oTab = document.getElementById("tab");
let oTabItem = oTab.querySelector(".tab-item");
let oLi = oTabItem.querySelectorAll("li");
let oTabContent = oTab.querySelectorAll(".tab-content");
for (let i = 0; i < oLi.length; i++) {
oLi[i].index = i;
oLi[i].onclick = function () {
for (let j = 0; j < oLi.length; j++) {
oLi[j].classList.remove("active");
oTabContent[j].classList.remove("active");
}
this.classList.add("active");
oTabContent[this.index].classList.add("active");
};
}
};
- 改写为面向对象
- 封装函数,尽量不要函数嵌套函数
- 可以有全局变量
- 把 onload 中不是赋值语句的代码提到单独的函数中
- 变量就是属性
- 函数就是方法
- 尽量让 this 指向对象
let oTab;
let oTabItem;
let oLi;
let oTabContent;
window.onload = function () {
const tab = new Tab();
tab.init();
};
function Tab() {
this.oTab = document.getElementById("tab");
this.oTabItem = this.oTab.querySelector(".tab-item");
this.oLi = this.oTabItem.querySelectorAll("li");
this.oTabContent = this.oTab.querySelectorAll(".tab-content");
}
Tab.prototype.init = function () {
const _that = this;
for (let i = 0; i < this.oLi.length; i++) {
this.oLi[i].index = i;
this.oLi[i].onclick = function () {
_that.change(this);
};
}
};
Tab.prototype.change = function (obj) {
for (let j = 0; j < this.oLi.length; j++) {
for (let j = 0; j < this.oLi.length; j++) {
this.oLi[j].classList.remove("active");
this.oTabContent[j].classList.remove("active");
}
obj.classList.add("active");
this.oTabContent[obj.index].classList.add("active");
}
};