面向过程
分析问题中的关键步骤,并将步骤封装成函数,然后按顺序依次调用即可。
面向对象
分析问题中的关系步骤,将这些步骤划分到不同的主体(对象)上,然后按顺序依次调用主体上的方法即可。
封装对象其实并不是为了解决问题,而是为了表示函数的所属关系。
代码演示
Document
封装
严格的来按面向对象的思想来书写代码。
多态
多种形态。
继承
一个对象使用另一个对象上的属性或方法
👉 以上三大特性是纯正的面向对象语言所具有的,但JavaScript并不是基于对象的语言,并不是面向对象的语言,所以,这三大特性在JS中的体现并不明显。
👉 构造函数,是面向对象三大特性的封装性的体现。
其目的
将数据与操作数据的方法定义到一个主体上,方法内通过this来访问数据。
实例化出来的每个对象上各自保留有自己的数据与操作数据的方法。
示例代码
/* 构造函数就是面向对象三大特性之一,封装性,在JS这种语言中的代码体现。 */ function Person(){this.age = 20; // 数据保存到对象的属性上this.say = function(){// 将操作数据的代码写到对象的方法上。 console.log(this.age);} }let obj = new Person() obj.age obj.say()// 通过构造函数,将数据,以及操作数据的代码,封装一对象上// 封装性代码体现就是,构造函数,
思考
同一个构造函数实例化出来的对象,每个对象上会保存各自的属性与方法。
对于属性中所保存的数据,很多时候是不同的,所以每个对象要有各自的属性。
但对于方法,来自同一个构造函数实例化出来的对象,所有的方法都是相同的,每个对象都保存一份,这会造成内存的浪费。
验证代码
=== 可以验证是不是同一个对象,同一个对象,同一个方法。
// 本小节主要引出一个小问题,通过这个问题去引出另一个知识点。 function Person(a,n){// 由于每个对象的属性数据不同,所以不写死,动态传递this.age = athis.name = n// 由于每个对象方法代码一般都是相同的,所以直接写死this.say = function(){// 无论当前构造函数,new出多少个对象,同一个方法内的代码是相同的,} }let oa = new Person(20,'zhangsan') let ob = new Person(22,'lisi')console.log(oa); console.log(ob);console.log(oa.say === ob.say); // false
原型对象
在JS中只要有一个函数存在,JS就会创建一个与之对应的对象。这个对象就是原型对象。
这个对象只有一个属性 constructor
原型对象的访问
原型对象不可以直接访问,只能通过函数或实例对象间接访问。
- 函数.prototype
- 实例对象.proto
示例代码
function Fn(){} console.log(Fn.prototype);let obj = new Fn(); console.log(obj.__proto__);
👉 构造函数与原型对象之间的关系 主要是体现在以下两个属性的相互指向上。
prototype
构造函数.prototype 指向 原型对象
constructor
原型对象.constructor 指向 构造函数
示例代码
function Person(){}// 构造函数是通过 prototype属性 "指向" 原型对象 console.log(Person.prototype);// 构造函数是通过 contructor 属性 "指向" 构造函数 console.log(Person.prototype.constructor);console.log(Person.prototype.constructor === Person);
👉 实例对象与原型对象之间的关系 主要是体现在__proto__这个属性上。
_proto_
实例对象._proto_ 指向 原型对象
示例代码
Document
👉 三角关系的主要体现在三个属性上
prototype
构造函数.prototype 指向 原型对象
constructor
原型对象.constructor 指向 构造函数
_proto_
实例对象._proto_ 指向 原型对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kGgmVTIx-1671867193274)(./assets/image-20220623142235739.png)]
原型对象上的成员会被所有的实例对象所共享
就是当一个实例对象访问某个成员时,如果不存在会自动到原型对象上找。
示例代码
// 首先在JS中任何一个对象上一级都有它的原型对象// 原型对象的特点 // 当某一个对象,访问一个成员(属性或方法)不存在时,会自动到它的原型对象上找这个成员进行使用。function Person(){// this.age = 20;}// 在原型对象上添加一个属性 age Person.prototype.age = 22let oa = new Person()console.log(oa.age);
👉 使用原则:所有实例共享(一份)保存到原型对象上,如果每个实例都要独有的(多份)定义在构造函数内。
原型对象也是可以被替换掉的
修改之前实例化的对象,访问之前的原型对象上的方法
修改之后实例化的对象,访问之后的原型对象上的方法
示例代码
// 默认:函数的原型对象是系统创建的,这个原型对象是可以被修改。 function Person(){}Person.prototype.a = 20;let oa = new Person(); console.log(oa.a);let abc = {}// ------------ 修改prototype的指向(让prototype属性指向另一个对象) Person.prototype = abc// 修改之后,实例化另一个对象 let ob = new Person();console.log(ob.a); console.log(oa.a);
👉 在JS中继承的方法有很多,这里我们只了解一种常用的 原型继承
原型继承
原型继承也称之为替换原型继承。
主要思想是 使用父的实例对象来替换子的原型对象。
代码实现:
// 继承: // 一个对象使用另一个对象上的成员// 使用父的实例(实例对象),来替换子的原型function A(){ // 父this.x = 100;this.y = 200;}let oA = new A() // 这是父的一个实例对象function B(){ // 子} // 使用父的实例(实例对象),来替换子的原型 B.prototype = oAlet oB = new B() console.log(oB.x); console.log(oB.y);/* 小结:JS中继承实现有很多种,使用父的实例,来修改子的原型。*/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OUMPT6sI-1671867193278)(assets/image-20220717153152960.png)]
什么是原型链
原型链是由原型对象形成的一个链条。
👉 原型链是通过__proto__形成的链接
示例代码
// 原型链:由原型对象形成的一个"链条"function Person(){}let oa = new Person()// 当一个对象访问某个成员,成员不存在时,会自动到原型对象上找。 // console.log(oa.age);// 原型对象也是对象,原型对象上在查找age属性时, // 如果没有,会到原型对象的原型对象上找这个属性 console.log(Person.prototype); // 一级原型 console.log(Person.prototype.__proto__); // 二级原型 console.log(Person.prototype.__proto__.__proto__); // null// 默认每一个原型对象都有一个函数与之对应 // 一级原型对应的构造函数 Person这个函数 二级原型对象的构造函数是 Object() // 验证 === console.log(Person.prototype.__proto__.constructor === Object);
原型链的查找规则
原型的作用是当实例对象上访问某个成员不存在时,则会到原型对象上找。
而原型链是当原型对象上访问某个成员不存在时,会到原型对象的原型对象上找。
这样就形成了一级一级向上找的过程。
就近原则,
示例代码
function Person(){}// Person.prototype.n = 10; Person.prototype.__proto__.n = 20;let oa = new Person(); console.log(oa.n);
语法:
对象 instanceof 函数
说明:
作用于判断构造函数与实例对象的关系,
依据是构造函数对应的原型对象是否在以实例为起点的原型链上。
示例代码
function Human(){}function Person(){}let oa = new Person(); console.log(oa instanceof Person); // true console.log(oa instanceof Human); // false console.log(oa instanceof Object); // true
面向对象思想分析
采用面向对象思想,先找对象,我们将弹窗当成一个对象。
构造函数体现面向对象代码体现,通过构造函数可以得到对象。
对象设计
弹窗标题 与 弹窗内容,可以看作是弹窗相关的数据,使用属性保存
弹窗需要一个html标签来显示页面效果,这个标签也看作弹窗的属性
弹窗要显示,所以弹窗需要具有显示的方法。
实现
function Modal(t, c) {this.title = tthis.content = cthis.el = document.createElement('div')this.el.className = 'modal'this.el.innerHTML = `
${this.title} x${this.content}`this.show = function () {document.body.appendChild(this.el)} }// 测试:删除按钮事件 document.querySelector('#delete').addEventListener('click', function(){let oM = new Modal('温馨提示','您无权删除')oM.show() })// 测试:登陆按钮事件 document.querySelector('#login').addEventListener('click', function(){let oM = new Modal('登陆成功', '正在为您跳转')oM.show() })
分析
同一时刻只能出现一个弹窗,这种就是模态弹窗
弹窗显示时,先获取页面获取弹窗用到的标签,如果有则不显示第2个,如果没有才显示
实现
function Modal(t, c) {this.title = tthis.content = cthis.el = document.createElement('div')this.el.className = 'modal'this.el.innerHTML = `
${this.title} x${this.content}`this.show = function () {// -------- 判断页面上是否有 弹窗存在if (!document.querySelector('.modal')) {document.body.appendChild(this.el)}} }// 测试:删除按钮事件 document.querySelector('#delete').addEventListener('click', function(){let oM = new Modal('温馨提示','您无权删除')oM.show() })// 测试:登陆按钮事件 document.querySelector('#login').addEventListener('click', function(){let oM = new Modal('登陆成功', '正在为您跳转')oM.show() })
分析
为关闭按钮注册事件,
事件内从body标签中将弹窗删除
实现
function Modal(t, c) {this.title = tthis.content = cthis.el = document.createElement('div')this.el.className = 'modal'this.el.innerHTML = `
${this.title} x${this.content}`this.show = function () {// 判断页面上是否有 弹窗存在if (!document.querySelector('.modal')) {document.body.appendChild(this.el)// -------- 为 关闭按钮 注册事件,document.querySelector('.modal .header i').addEventListener('click', function(){// -------- 在事件内将 .modal 元素从页面里移除即可document.body.removeChild(document.querySelector('.modal'))})}} }// 测试:删除按钮事件 document.querySelector('#delete').addEventListener('click', function(){let oM = new Modal('温馨提示','您无权删除')oM.show() })// 测试:登陆按钮事件 document.querySelector('#login').addEventListener('click', function(){let oM = new Modal('登陆成功', '正在为您跳转')oM.show() })