JS进阶 3——深入面向对象、原型

server/2024/10/9 4:23:25/

JS 进阶3——深入面向对象、原型

1.编程思想

  • 面向过程:分析出解决问题的过程,然后用函数将这些步骤一步步封装起来
  • 面向对象:将事物分为一个个对象,然后对象之间分工合作

2.构造函数:封装性、面向对象

  • 构造函数方法存在浪费内存的问题(构造函数中的方法每次调用)

      function Star(name, age) {this.name = namethis.age = agethis.sing = function () {console.log('我会唱歌')}}const xxg = new Star('小小怪', 18)const ddg = new Star('大大怪', 22)console.log(xxg.sing === ddg.sing) //返回false,重复创建两个sing
    

3.原型——解决构造函数浪费内存的问题

  • 什么是原型

    • 构造函数通过原型分配的函数是所有对象所共享的
    • JS中,每个构造函数都有一个prototype属性,指向另一个对象,称为原型对象
    • 原型对象可以挂载函数,对象实例化不会多次创建原型上函数,节约内存
    • 可以把不变的方法直接定义到prototype对象上,这样所有对象的实例可以共享这些方法
    • 构造函数和原型对象中的this都指向实例化的对象
    //1.公共属性写到构造函数中function Star(name, age) {this.name = namethis.age = age}
    //2.公共方法写到原型对象身上Star.prototype.sing = function () {console.log('唱歌');}const xxg = new Star('小小怪', 18)const ddg = new Star('大大怪', 22)xxg.sing()ddg.sing()console.log(xxg.sing === ddg.sing) //返回true
    

    eg:为数组对象添加方法(注意想要不传参,就要使用this指向实例对象)

     //为数组拓展 求最大值方法Array.prototype.max = function () {return Math.max(...this)}//为数组拓展 求和方法Array.prototype.sum = function () {return this.reduce((prev, current) => prev + current)}const str = [1, 2, 3]console.log(str.max())console.log(str.sum())
    
  • constructor(构造函数)属性

    • 每个原型对象中都有一个constructor属性
    • 该属性指向该原型对象的构造函数,标明该原型对象属于哪个构造函数
    //创建一个构造函数function Star() {}//想要为该构造函数一次性挂载多个方法Star.prototype = {//重新指回创造这个原型对象的构造函数constructor: Star,sing: function () {console.log('我喜欢唱歌');},dance: function () {console.log('我喜欢跳舞');}}console.log(Star.prototype) //返回undefined//意味着找不到该原型对象的构造函数了//解决办法:在原型对象中重新指回创造这个原型对象的构造函数
    
  • 对象原型

    • 对象都会有一个 __ proto__ 指向构造函数的prototype原型对象,之所以对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象 __ proto __ 的存在
    • 只能获取不能赋值
    • 对象原型是实例对象的属性,指向原型对象,有一个属性constructor指向构造函数;原型对象是构造函数的属性,是一个对象,也有一个属性constructor指向构造函数
     function Star() { }const ldh = new Star()console.log(ldh.__proto__ === Star.prototype)//返回true
    
  • 原型继承

    • 借助原型对象实现继承的特性
        //人 父构造函数function People() {this.eyes = 2this.head = 1}//女人  构造函数 继承Peoplefunction Woman() {}//子类的原型 = new 父类,方便给子类添加特殊的属性和方法Woman.prototype = new People()//指回构造函数Woman.prototype.constructor = Woman//给女人添加方法Woman.prototype.baby = function () {console.log('宝贝')}const red = new Woman()console.log(red)//男人  构造函数 继承Peoplefunction Man() {}Man.prototype = new People()Man.prototype.constructor = Manconst blue = new Man()console.log(blue)
    
  • 原型链:就是一个查找规则,先从自身原型对象查找属性和方法,找不到就往上一层查找,原型链就是往上查找的这样一个路线。

在这里插入图片描述

  • instanceof运算符:用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上
  • 案例:使用原型实现模态框封装:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>面向对象封装消息提示</title><style>.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>
</head><body><button id="delete">删除</button><button id="login">登录</button><!-- <div class="modal"><div class="header">温馨提示 <i>x</i></div><div class="body">您没有删除权限操作</div></div> --><script>javascript">//构造函数封装——模态框function Modal(title = '', message = '') {//创建div标签this.modalBox = document.createElement('div')//给div标签添加类名为modalthis.modalBox.className = 'modal'//modal盒子内部填充2个div标签并且修改文字内容this.modalBox.innerHTML = `<div class="header">${title} <i>x</i></div><div class="body">${message}</div>`console.log(this.modalBox)}Modal.prototype.open = function () {const box = document.querySelector('.modal')//防止创建多个模态框,使其有则移除,没有就继续执行box && box.remove()document.body.append(this.modalBox)//x要在模态框创建完成后才能点击关闭this.modalBox.querySelector('i').addEventListener('click', () => {this.close()})}Modal.prototype.close = function () {this.modalBox.remove()}document.querySelector('#delete').addEventListener('click', () => {const del = new Modal('温馨提示', '您没有权限删除操作')del.open()})document.querySelector('#login').addEventListener('click', () => {const login = new Modal('友情提示', '您没有注册呢?')login.open()})</script>
</body></html>

http://www.ppmy.cn/server/129092.html

相关文章

类与对象、封装、继承和多态

文章目录 一、类与对象什么是对象什么是类什么是面向对象如何定义类如何new对象 二、继承什么是继承如何实现继承继承的特点和要求继承属性和方法不会继承父类的构造器 子类可以重写父类的方法方法重载和重写的区别Object类toString的重写super关键字 三、多态什么是多态运行时…

盘点2024年4款打工人都在用的PDF软件。

PDF 软件在现代的办公或者是学习当中的应用非常广泛&#xff0c;已经成了很多人的必备工具。因为PDF 文件具有跨设备、跨系统的优势&#xff0c;所以在很多设备上都可以打开浏览。如果有了PDF 编辑软件&#xff0c;查看&#xff0c;编辑&#xff0c;分享也会变得更加方便简单&a…

CSS面试真题 part1

CSS面试真题 part1 1、说说你对盒子模型的理解2、谈谈你对BFC的理解3、什么是响应式设计&#xff1f;响应式设计的基本原理是什么&#xff1f;如何做&#xff1f;4、元素水平垂直居中的方法有哪些&#xff1f;如果元素不定宽高呢&#xff1f;5、如何实现两栏布局&#xff0c;右…

【Qt】窗口预览(1)—— 菜单栏

窗口预览&#xff08;1&#xff09; 1. QMainWindow2. QMenuBar——菜单栏2.1 创建菜单栏/将菜单栏添加到widget中2.2 addMenu——在菜单栏中添加菜单2.3 在菜单中添加选项2.4 添加快捷键2.5 支持嵌套添加菜单2.6 添加信号2.7 添加分割线 1. QMainWindow Qt窗口是通过QMainWin…

Nginx06-静态资源部署

零、文章目录 Nginx06-静态资源部署 1、静态资源概述 静态资源&#xff1a;是在Web开发中不经常改变的文件&#xff0c;比如图片、CSS样式表、JavaScript脚本文件等。这些资源通常是预先编译好的&#xff0c;不需要服务器端的动态处理。动态资源&#xff1a;是在Web开发中需…

springboot 打包部署jsp页面两种方式war/jar

springboot 两种部署方式jsp页面 war包部署jsp页面 我们是用传统的war包,放到 tomcat的webapp目录里面,当容器启动的时候,会自动解压.war 文件,从而进行访问,但是 springboot 是内嵌的tomcat,所以我们需要排除内嵌的tomcat 使之失效 1、排除依赖jar包 <dependency>…

自动驾驶系列—解析自动驾驶汽车的“大脑”:电子电气架构详解与选型指南

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

WPF入门教学二十三 自定义控件开发

在WPF&#xff08;Windows Presentation Foundation&#xff09;中&#xff0c;自定义控件开发是一项强大的功能&#xff0c;它允许开发者根据特定需求创建独特的用户界面元素。自定义控件可以是简单的用户控件&#xff0c;也可以是更复杂的继承自现有控件的自定义控件。以下是…