个性化网站建设,东莞教育建站,wordpress后台用户名和密码,做代练去什么网站安全吗#x1f954;#xff1a;永远做自己的聚光灯 JS进阶-Day1——点击此处#xff08;作用域、函数、解构赋值等#xff09; JS进阶-Day2——点击此处#xff08;深入对象之构造函数、实例成员、静态成员等#xff1b;内置构造函数之引用类型、包装类型等#xff09; 更多JS… 永远做自己的聚光灯 JS进阶-Day1——点击此处作用域、函数、解构赋值等 JS进阶-Day2——点击此处深入对象之构造函数、实例成员、静态成员等内置构造函数之引用类型、包装类型等 更多JS知识——点击此处 JS进阶-Day3 编程思想面向过程面向对象面向过程和面向对象的对比 构造函数原型原型对象案例给数组扩展方法面试小题⭐: constructor 属性对象原型复习小题⭐ 原型继承重要原型链重要面试小题⭐: 案例消息提示对象封装 了解构造函数原型对象的语法特征掌握 JavaScript 中面向对象编程的实现方式基于面向对象编程思想实现 DOM 操作的封装。 了解面向对象编程的一般特征掌握基于构造函数原型对象的逻辑封装掌握基于原型对象实现的继承理解什么原型链及其作用能够处理程序异常提升程序执行的健壮性
编程思想 学习 JavaScript 中基于原型的面向对象编程序的语法实现理解面向对象编程的特征。 面向过程
面向过程就是分析出解决问题所需要的步骤然后用函数把这些步骤一步一步实现使用的时候再一个一个的依次调用就可以了。
举个栗子蛋炒饭 面向对象
面向对象是把事务分解成为一个个对象然后由对象之间分工与合作。
举个栗子盖浇饭 在面向对象程序开发思想中每一个对象都是功能中心具有明确分工。
面向对象编程具有灵活、代码可复用、容易维护和开发的优点更适合多人合作的大型软件项目。
面向对象的特性
封装性继承性多态性 面向过程和面向对象的对比
面向过程编程
优点性能比面向对象高适合跟硬件联系很紧密的东西例如单片机就采用的面向过程编程。
缺点没有面向对象易维护、易复用、易扩展。
面向对象编程
优点易维护、易复用、易扩展由于面向对象有封装、继承、多态性的特性可以设计出低耦合的系统使系统更加灵活、更加易于维护。
缺点性能比面向过程低。
构造函数
对比以下通过面向对象的构造函数实现的封装
scriptfunction Person() {this.name 佚名// 设置名字this.setName function (name) {this.name name}// 读取名字this.getName () {console.log(this.name)}}// 实例对象获得了构造函数中封装的所有逻辑let p1 new Person()p1.setName(小明)console.log(p1.name) //小明// 实例对象let p2 new Person()console.log(p2.name) //佚名
/script封装是面向对象思想中比较重要的一部分js面向对象可以通过构造函数实现封装。 同样的将变量和函数组合到了一起并能通过 this 实现数据的共享所不同的是借助构造函数创建出来的实例对象之间是彼此不影响的。 总结 构造函数体现了面向对象的封装特性构造函数实例创建的对象彼此独立、互不影响 前面我们学过的构造函数方法很好用但是存在浪费内存的问题。
我们希望所有的对象使用同一个函数这样就比较节省内存那么我们要怎样做呢下面介绍原型可以帮助我们解决这个问题。
原型
原型对象
目标能够利用原型对象实现方法共享 构造函数通过原型分配的函数是所有对象所共享的。 JavaScript 规定每一个构造函数都有一个 prototype 属性指向另一个对象所以我们也称为原型对象 这个对象可以挂载函数对象实例化不会多次创建原型上函数节约内存 我们可以把那些不变的方法直接定义在 prototype 对象上这样所有对象的实例就可以共享这些方法。 构造函数和原型对象中的this都指向实例化的对象
scriptfunction Person() {}// 每个函数都有 prototype 属性console.log(Person.prototype) //Object
/script了解了 JavaScript 中构造函数与原型对象的关系后再来看原型对象具体的作用如下代码所示
script//公共的属性写在构造函数里function Person(uname, age) {this.uname name;this.age age;// 此处未定义任何方法}// 为构造函数的原型对象添加方法公共的方法写在原型对象里Person.prototype.sayHi function () {console.log(Hi~);}// 实例化let p1 new Person(potato,18);p1.sayHi(); // 输出结果为 Hi~
/script构造函数 Person 中未定义任何方法这时实例对象调用了原型对象中的方法 sayHi接下来改动一下代码
scriptfunction Person() {// 此处定义同名方法 sayHithis.sayHi function () {console.log(嗨!);}}// 为构造函数的原型对象添加方法Person.prototype.sayHi function () {console.log(Hi~);}let p1 new Person();p1.sayHi(); // 输出结果为 嗨!
/script构造函数 Person 中定义与原型对象中相同名称的方法这时实例对象调用则是构造函中的方法 sayHi。
通过以上两个简单示例不难发现 JavaScript 中对象的工作机制当访问对象的属性或方法时先在当前实例对象是查找然后再去原型对象查找并且原型对象被所有实例共享。
scriptfunction Person() {// 此处定义同名方法 sayHithis.sayHi function () {console.log(嗨! this.name)}}// 为构造函数的原型对象添加方法Person.prototype.sayHi function () {console.log(Hi~ this.name)}// 在构造函数的原型对象上添加属性Person.prototype.name 小明let p1 new Person()p1.sayHi(); // 输出结果为 嗨!let p2 new Person()p2.sayHi()
/script总结结合构造函数原型的特征实际开发重往往会将封装的功能函数添加到原型对象中。
案例给数组扩展方法
需求
①给数组扩展求最大值、最小值方法和求和方法
比如以前学过
constarr [1,2,3]
arr.reverse() 结果是[3,2,1]
扩展完毕之后arr.sum()返回的结果是6
script//给数组拓展方法 例求最大值、最小值、和//1.我们定义的这个方法任何一个数组实例对象都可以使用//2.自定义的方法写到 数组.prototype上//求最大值Array.prototype.max function () {//展开运算符return Math.max(...this);};//求最小值Array.prototype.min function () {//展开运算符return Math.min(...this);};//求和Array.prototype.sum function () {return this.reduce((prev, item) prev item, 0);};//使用const arr [1, 2, 4, 9];console.log(arr.max());console.log([2, 4, 1, 6].min());console.log(arr.sum());
/script面试小题⭐:
1、原型是什么
一个对象我们也称prototype为原型对象
2、原型的作用是什么
共享方法可以把不变的的方法直接定义在prototype对象上可以节省内存
3、构造函数和原型里面的this指向谁
实例化的对象
constructor 属性
每个原型对象里面都有个constructor 属性constructor 构造函数
作用该属性指向该原型对象的构造函数 简单理解就是指向我的爸爸我是有爸爸的孩子
使用场景
如果有多个对象的方法我们可以给原型对象采取对象形式赋值。
但是这样就会覆盖构造函数原型对象原来的内容这样修改后的原型对象 constructor 就不再指向当前构造函数了
此时我们可以在修改后的原型对象中添加一个 constructor 指向原来的构造函数。 对象原型
思考构造函数可以创建实例对象构造函数还有一个原型对象一些公共的属性或者方法放到这个原型对象身上。但是为啥实例对象可以访问原型对象里面的属性和方法呢 对象都会有一个属性__ proto__ 指向构造函数的 prototype 原型对象之所以我们对象可以使用构造函数 prototype原型对象的属性和方法就是因为对象有 __ proto__原型的存在。
注意
__ proto__ 是JS非标准属性[[prototype]]和__ proto__意义相同用来表明当前实例对象指向哪个原型对象prototype__ proto__对象原型里面也有一个 constructor属性指向创建该实例对象的构造函数__ proto__是实例对象里的对象原型对象原型指向原型对象
注分清原型对象和对象原型分别是什么。
总结可以理解为构造函数是父亲原型原型对象是大儿子实例对象是小儿子原型和实例对象是亲兄弟。大儿子有一个constructor属性指向父亲构造函数证明“这是我爸爸”小儿子有一个__ proto__ (对象原型)里面有一个constructor属性指向父亲构造函数证明“这是我爸爸”而实例对象有一个__ proto__对象原型指向哥哥原型对象证明“这是我哥哥”(仅用于理解) 复习小题⭐
1、prototype是什么哪里来的
原型原型对象每一个构造函数都自动有一个原型
2、constructor属性在哪里作用
这个属性在__ proto__对象原型和prototype原型对象里都要都指向创建实例对象/原型的构造函数
3、__ proto__属性在哪里指向谁
这个属性在实例对象里指向原型prototype
原型继承重要
面向对象的三大特性封装、继承、多态。
继承是面向对象编程的另一个特征通过继承进一步提升代码封装的程度JavaScript 中大多是借助原型对象实现继承的特性。
龙生龙、凤生凤、老鼠的儿子会打洞描述的正是继承的含义。
①我们来看个代码 ②封装—抽取公共部分
把男人和女人公共的部分抽取出来放到人类里面
③继承—让男人和女人都能继承人类的一些属性和方法
把男人女人公共的属性和方法抽取出来People然后赋值给Man的原型对象可以共享这些属性和方法注意让constructor指回Man这个构造函数 问题如果我们给男人添加了一个吸烟的方法发现女人自动也添加这个方法 原因男人和女人都同时使用了同一个对象根据引用类型的特点他们指向同一个对象修改一个就会都影响
解决男人和女人不要使用同一个对象但是不同对象里面包含相同的属性和方法构造函数new 每次都会创建一个新的对象 完善上述代码 示例
bodyscript// 继续抽取 公共的部分放到原型上// const Person1 {// eyes: 2,// head: 1// }// const Person2 {// eyes: 2,// head: 1// }// 构造函数 new 出来的对象 结构一样但是对象不一样function Person() {this.eyes 2this.head 1}// console.log(new Person)// 女人 构造函数 继承 想要 继承 Personfunction Woman() {}// Woman 通过原型来继承 Person// 父构造函数父类 子构造函数子类// 子类的原型 new 父类 Woman.prototype new Person() // {eyes: 2, head: 1} // 指回原来的构造函数Woman.prototype.constructor Woman// 给女人添加一个方法 生孩子Woman.prototype.baby function () {console.log(宝贝)}const red new Woman()console.log(red)// console.log(Woman.prototype)// 男人 构造函数 继承 想要 继承 Personfunction Man() {}// 通过 原型继承 PersonMan.prototype new Person()Man.prototype.constructor Manconst pink new Man()console.log(pink)/script
/body原型链重要
复习 作用域链—本质上是底层的变量查找机制。 原型链—查找一个对象属性包括方法的一种查找规则。
基于原型对象的继承使得不同构造函数的原型对象关联在一起并且这种关联的关系是一种链状的结构我们将原型对象的链状结构关系称为原型链。
只要是对象就有对象原型__ proto__只要是原型对象就有constructor。 示例
bodyscript// function Objetc() {}console.log(Object.prototype)console.log(Object.prototype.__proto__)function Person() {}const ldh new Person()console.log(ldh.__proto__ Person.prototype) //trueconsole.log(Person.prototype.__proto__ Object.prototype) //true//instanceof运算符的使用console.log(ldh instanceof Person) //trueconsole.log(ldh instanceof Object) //trueconsole.log(ldh instanceof Array) //falseL(是对象不是数组)console.log([1, 2, 3] instanceof Array) //trueconsole.log(Array instanceof Object) //true(万物皆对象)/script
/body原型链查找规则
① 当访问一个对象的属性包括方法时首先查找这个对象自身有没有该属性。
② 如果没有就查找它的原型也就是 __ proto__指向的 prototype 原型对象
③ 如果还没有就查找原型对象的原型Object的原型对象
④ 依此类推一直找到 Object 为止null
⑤ __ proto__对象原型的意义就在于为对象成员查找机制提供一个方向或者说一条路线
⑥ 可以使用 instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
面试小题⭐:
1、原型链是什么 原型链可以理解为一种对象的属性、方法的一种查找机制。 具体的查找机制是 当访问一个对象的属性包括方法时先在这个对象本身找如果找不到的话查找这个对象的原型对象依此类推一直找到Object为止如果Object也没有则返回null。
2、如何检测一个构造函数 的原型是否出现在某个实例对象的原型链上
使用instanceof运算符可以判断。
案例消息提示对象封装
目的练习面向对象写插件模态框
分析需求 定义模态框Modal 构造函数用来创建对象 模态框具备打开功能open 方法按钮点击可以打开模态框 模态框具备关闭功能close 方法
问open 和close 方法写到哪里
构造函数的原型对象上共享方法
所以可以分为三个模块构造函数open方法close方法
步骤
①Modal 构造函数制作 需要的公共属性标题title、提示信息内容message可以设置默认参数 在页面中创建模态框 (1)创建div标签可以命名为modalBox (2)div标签的类名为modal (3)标签内部添加基本结构并填入相关数据
②open方法
写到构造函数的原型对象身上把刚才创建的modalBox添加到页面body 标签中open 打开的本质就是把创建标签添加到页面中点击按钮实例化对象传入对应的参数并执行open 方法
③close方法 写到构造函数的原型对象身上 把刚才创建的modalBox从页面body 标签中删除 需要注意x 删除按钮绑定事件要写到open里面添加 因为open是往页面中添加元素同时顺便绑定事件
!DOCTYPE html
html langenheadmeta charsetUTF-8 /meta http-equivX-UA-Compatible contentIEedge /meta nameviewport contentwidthdevice-width, initial-scale1.0 /title面向对象封装消息提示/titlestyle.modal {width: 300px;min-height: 100px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);border-radius: 4px;position: fixed;z-index: 999;left: 50%;top: 50%;transform: translate3d(-50%, -50%, 0);background-color: #fff;}.modal .header {line-height: 40px;padding: 0 10px;position: relative;font-size: 20px;}.modal .header i {font-style: normal;color: #999;position: absolute;right: 15px;top: -2px;cursor: pointer;}.modal .body {text-align: center;padding: 10px;}.modal .footer {display: flex;justify-content: flex-end;padding: 10px;}.modal .footer a {padding: 3px 8px;background: #ccc;text-decoration: none;color: #fff;border-radius: 2px;margin-right: 10px;font-size: 14px;}.modal .footer a.submit {background-color: #369;}/style/headbodybutton iddelete删除/buttonbutton idlogin登录/button!-- div classmodaldiv classheader温馨提示 ix/i/divdiv classbody您没有删除权限操作/div/div --script// 1. 模态框的构造函数function Modal(title , message ) {// 公共的属性部分this.title title;this.message message;// 因为盒子是公共的// 1. 创建 一定不要忘了加 thisthis.modalBox document.createElement(div);// 2. 添加类名this.modalBox.className modal;// 3. 填充内容 更换数据this.modalBox.innerHTML div classheader${this.title} ix/i/divdiv classbody${this.message}/div;// console.log(this.modalBox)}// 2. 打开方法 挂载 到 模态框的构造函数原型身上Modal.prototype.open function () {if (!document.querySelector(.modal)) {// 把刚才创建的盒子 modalBox 渲染到 页面中 父元素.appendChild(子元素)document.body.appendChild(this.modalBox);// 获取 x 调用关闭方法this.modalBox.querySelector(i).addEventListener(click, () {// 箭头函数没有this 上一级作用域的this// 这个this 指向 mthis.close();});}};// 3. 关闭方法 挂载 到 模态框的构造函数原型身上Modal.prototype.close function () {document.body.removeChild(this.modalBox);};// 4. 按钮点击document.querySelector(#delete).addEventListener(click, () {const m new Modal(温馨提示, 您没有权限删除);// 调用 打开方法m.open();});// 5. 按钮点击document.querySelector(#login).addEventListener(click, () {const m new Modal(友情提示, 您还没有注册账号);// 调用 打开方法m.open();});/script/body
/html