JavaScript面向对象介绍、创建对象的方式、构造函数的使用、构造函数的不合理、原型

一、面向对象介绍

 1.了解面向对象+ 面向对象是我们的一种开发方式+ 面向过程: 一种关注过程的开发方式=> 在开发过程中, 我们要关注每一个细节, 步骤, 顺序+ 面向对象: 一种面向对象的开发方式=> 在开发过程中, 我们看看有没有一个对象能帮我们完成任务例子: 一份烤鸭+ 面向过程=> 所有事情都是我们自己做的=> 考虑顺序-> 先杀鸭子, 先考鸭子, 先切鸭子=> 考虑步骤-> 杀鸭子的时候, 先干什么, 后干什么=> 考虑细节-> 胡萝卜, 切宽窄程度->, 咸淡口味+ 面向对象=> 只需要点一份烤鸭=> 等待结果2.开发过程中的例子: 选项卡+ 面向过程=> 考虑获取那些元素=> 考虑给那些元素绑定点击事件=> 考虑点击的时候, 做什么+ 面向对象=> 考虑有没有一个对象能帮我们完成选项卡=> 如果有, 那么我就直接让这个对象帮我完成=> 如果没有, 我们就需要制造一个这样的对象来帮我完成+ 我们需要一个 "机器"=> 这个机器能给我生产一个对象=> 生产出来的对象能完成选项卡功能=> 我们只要准备好这个机器就可以了=> 本次开发过程中, 我们制造机器, 制造好以后, 用机器生成一个对象完成选项卡=> 当你第二次想进行选项卡开发的时候, 那么我们不需要再次制造机器了=> 只要用原先准备好的机器, 再次制造一个新的选项卡对象+ 我们制造 "机器" 得 过程, 就是面向对象封装的过程=> 面向对象的核心: 高内聚低耦合(就是对面向过程的高度封装)3.核心:+ 找到一个机器, 能批量生产对象+ 生产出来的对象, 每一个对象都有自己的属性和方法+ 每一个对象可能类似, 但是内容不太一样=> 构造函数=> 可以批量生产对象=> 可以向函数一样传递参数, 可以给每一个对象添加一些不同的内容=> 当你需要完成一个功能的时候, 我们先制造一个构造函数-> 利用构造函数去创建一个可以完成任务的对象-> 依赖这个对象完成功能+ 这个 "机器"(构造函数) 要生产有属性有方法的合理的对象=> 机器: 就是构造函数=> 属性: 直接写在构造函数体内=> 方法: 写在构造函数的原型上4.面向对象开发+ 选项卡1. 书写一个构造函数2. 创建一个能够完成选项卡的对象=> 属性: 选项卡中能够点击的按钮=> 属性: 选项卡中用于切换的盒子=> 方法: 控制点击的按钮添加点击事件, 给盒子进行切换操作3. 使用构造函数创建一个选项卡对象

二、创建对象的方式

<script>创建对象的方式1. 字面量方式创建对象+ var obj = { ... }+ 可以后期动态添加2. 内置构造函数创建对象+ var obj = new Object()+ 可以后期动态添加3. 工厂函数创建对象3-1. 制造一个工厂函数3-2. 使用工厂函数去创建对象4. 自定义构造函数创建对象4-1. 制造一个自定义构造函数4-2. 使用自定义构造函数去创建对象1. 字面量方式创建对象var obj = {name: 'Jack',age: 18,sayHi: function () { console.log('hello world') }}如果我想创建第二个对象var obj2 = {name: 'Rose',age: 20,sayHi: function () {console.log('hello world')}}2. 内置构造函数创建对象var obj = new Object()obj.name = 'Jack'obj.age = 18obj.sayHi = function () { console.log('hello world') }3. 工厂函数创建对象3-1. 创建工厂函数function createObj(name, age) {手动创建一个对象var obj = {}手动想里面添加属性obj.name = nameobj.age = ageobj.sayHi = function () { console.log('hello world') }手动返回这个对象return obj}3-2. 使用工厂函数去创建对象var obj1 = createObj('Jack', 18)var obj2 = createObj('Rose', 20)console.log(obj1, obj2)4. 自定义构造函数创建对象4-1. 制造一个自定义构造函数构造函数会自动创建对象, 自动返回这个对象我们只需要手动想里面添加内容就可以了function createObj(name, age) {自动创建对象手动向对象里面添加成员这里的  this 指向当前实例(new 前面的变量)this.name = namethis.age = agethis.sayHi = function () { console.log('hello world') }自动返回对象}4-2. 使用自定义构造函数去创建对象构造函数在使用的时候, 需要和 new 关键字连用如果不连用, 那么没有意义第一次调用 createObj 的时候,new 关键字连用了我们 createObj 里面的 this 指向了 obj1函数内部的代码在执行的时候, 就是在向 obj1 添加了 name age 和 sayHi 三个成员var obj1 = new createObj('Jack', 18)第二次调用 createObj 的时候,new 关键字连用了我们的 createObj 里面的 this 指向了 obj2函数内部的代码在执行的时候, 就是在向 obj2 添加了 name age 和 sayHi 三个成员var obj2 = new createObj('Rose', 20)console.log(obj1, obj2)</script>

三、构造函数的使用

<script>构造函数的使用1. 构造函数和普通函数没有区别=> 只不过在调用的时候和 new 关键字连用2. 书写构造函数, 函数名首字母大写=> 当你看到名字的时候, 就知道要和 new 关键字连用3. 调用的时候, 需要和 new 关键字连用=> 因为只有和 new 关键字连用的时候, 这个函数才会有自动创建和返回对象的能力=> 因为我们之所以书写构造函数, 就是为了使用它去批量生产对象=> 如果不和 new 关键字连用, 那么该函数没有创建对象的能力, 没有自动返回对象的能力4. 调用构造函数的时候, 如果不需要传递参数=> 可以不写最后的小括号=> 如果你需要传递参数, 那么必须写小括号=> 但是书写规范推荐我们都写上小括号5. 当你的函数名 和 new 关键字连用的时候=> 函数内部的 this 指向当前实例(new 关键字前面的变量)=> 我们直接在函数体内书写 this.xxx =-> 就是在向自动创建出来的对象里面添加内容6. 构造函数内部不要对边写 return=> 当你 return 了一个基本数据类型的时候, 写了白写=> 当你 return 了一个复杂数据类型的时候, 构造函数白写function person() {console.log('hello world')}function Person() {this.name = 'Jack'}3.var obj = new Person()console.log(obj)var obj2 = Person()console.log(obj2)4.var obj = new Person() // 推荐console.log(obj)var obj2 = new Person // 不推荐console.log(obj2)6.function Person() {this.name = 'Jack'this.age = 18return 基本数据类型return 'true'return 复杂数据类型return [1, 2, 3]}var obj = new Person()console.log(obj)</script>

四、构造函数的不合理

<script>构造函数的不合理+ 当你在构造函数体内书写方法的时候=> 你需要向对象上添加方法的时候=> 只要创建一次对象(new 一次) 就会有一个函数在占用空间=> 创建 100 次对象, 会有 100 个一模一样的函数出现+ 100 个函数一模一样=> 但是其实里面有 99 个是重复的, 没有必要存在1. 准备一个构造函数function Person(name, age) {this.name = namethis.age = agethis.sayHi = function () { console.log('hello world') }}2. 创建对象var p1 = new Person('Jack', 18)var p2 = new Person('Rose', 20)console.log(p1, p2)调用两个对象的 sayHi 方法p1.sayHi()p2.sayHi()看一下是不是真的是两个对象console.log(p1 == p2) // false, 确实是两个对象两个对象里面的函数console.log(p1.sayHi)console.log(p2.sayHi)console.log(p1.sayHi == p2.sayHi) // false, 是两个函数var p1 = new Person('Jack', 18)var p2 = new Person('Rose', 20)p1 第一次执行 Person 函数=> 会吧函数内部的 this 指向 p1=> 会吧函数体内的代码全部执行一遍=> 向 p1 上添加 name 属性=> 向 p1 上添加 age 属性=> 向 p1 上添加 sayHi 方法, 会创建一个函数出来p2 第二次执行 Person 函数=> 会吧函数内部的 this 指向 p2=> 会吧函数体内的代码全部执行一遍=> 向 p2 上添加 name 属性=> 向 p2 上添加 age 属性=> 向 p2 上添加 sayHi 方法, 会创建一个函数出来</script>

五、原型

<script>原型 prototype+ 定义: 每一个函数天生自带一个属性, 叫做 prototype, 是一个对象+ 构造函数也是函数, 也会有这个自带的空间 prototype+ 既然 prototype 是一个对象, 我们就可以使用对象操作的语法, 向里面添加一些内容对象+ 定义: 每一个对象, 在你访问他的成员的时候, 如果自己没有这个属性=> 会自动去所属构造函数的 prototype 上查找+ 自定义构造函数创建的对象也是对象, 当你访问某一个成员的时候=> 如果没有, 也会自动去所属构造函数的原型上查找=> 哪一个构造函数创建的对象, 这个对象就属于哪一个构造函数=> 因为构造函数在创建对象的过程, 我们起名为 实例化 的过程-> 创建出来的对象叫做这个构造函数的一个 实例化对象function Person() {}Person.prototype.sayHi = function () { console.log('我是 Person 原型上的方法') }console.log(Person.prototype)创建一个实例化对象因为 p1 是 Person 实例化出来的对象p1 就是属于 Person 这个构造函数的当你访问 p1 的 sayHi 成员的时候, p1 自己是没有的会自动去 Person 的 原型(prototype) 上查找var p1 = new Person()console.log(p1)p1.sayHi()创建第二个实例化对象因为 p2 也是 Person 的实例化对象p2 没有 sayHi 成员, 也会自动去 Person 的原型上查找var p2 = new Person()console.log(p2)p2.sayHi()p1 的 sayHi 方法和 p2 的 sayHi 方法都是使用的 Person 构造函数的原型上的方法我只要向 Person 的原型上添加一些方法所有的 Person 的每一个实例都可以使用并且使用的都是同一个函数, 不会出现浪费空间的行为console.log(p1.sayHi === p2.sayHi) // true 说明是一个函数
</script>

六、面向对象作业

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>* {margin: 0;padding: 0;}ul,ol,li {list-style: none;}.tab {width: 600px;height: 400px;border: 10px solid #333;margin: 50px auto;display: flex;/* 创建弹性(Flex)容器 */flex-direction: column;/* 设置子元素垂直排列 */}ul {height: 60px;display: flex;}ul>li {flex: 1;/* 使用 flex: 1; 使弹性项目平均分配剩余空间 */display: fex;/* 创建弹性(Flex)容器 */justify-content: center;/* 主轴上的对齐方式为居中对齐 */align-items: center;/* 侧轴上的对齐方式为居中对齐 */font-size: 40px;color: #fff;background-color: skyblue;cursor: pointer;}ul>li.active {background-color: orange;}ol {flex: 1;position: relative;}ol>li {position: absolute;left: 0;top: 0;width: 100%;height: 100%;font-size: 100px;color: #fff;background-color: purple;display: none;justify-content: center;align-items: center;}ol>li.active {display: flex;}</style>
</head><body><div class="tab" id="box"><ul><li class="active">1</li><li>2</li><li>3</li></ul><ol><li class="active">1</li><li>2</li><li>3</li></ol></div><div class="tab" id="box2"><ul><li class="active">1</li><li>2</li><li>3</li><li>4</li></ul><ol><li class="active">1</li><li>2</li><li>3</li><li>4</li></ol></div><div class="tab" id="box3"><ul><li class="active">1</li><li>2</li><li>3</li></ul><ol><li class="active">1</li><li>2</li><li>3</li></ol></div><script>/*简单版面向对象选项卡1.抽象内容+ 一个能够完成选项卡的对象,需要有哪些属性和方法+ 属性:所有可以点击的按钮盒子+ 属性:所有可以切换的选项盒子+ 方法:能添加点击事件的方法2.书写构造函数+ 能创建一个对象,包含两个属性和一个方阿飞+ 属性直接写在构造函数体内+ 方法写在构造函数的原型上*///2.书写构造函数function Tabs(ele) {//范围this.ele = document.querySelector(ele);;//在范围内找到所有可以点击的盒子this.btns = this.ele.querySelectorAll('ul>li')//在范围内找到所有可以切换的盒子this.tabs = this.ele.querySelectorAll('ol>li')}//原型上书写方法Tabs.prototype.change = function () {//执行所有btns里面的按钮添加点击事件//怎么拿到btns//不能不能直接使用t这个变量// console.log(this.btns)//提前保存一下thisvar _this = this;for (var i = 0; i < this.btns.length; i++) {//提前保存索引this.btns[i].setAttribute('index', i);this.btns[i].addEventListener('click', function () {console.log('点击我一下啊')//需要让实例的btns里面的每一个没有active类名//需要让实例的tabs里面的每一个没有active类名//这里不是在change函数的作用域,而是事件处理函数的作用域//在事件处理函数里面,this指向当前事件的事件源// console.log(_this)//当你访问_this的时候,其实就是访问变量//自己作用域没有,就会去上一级作用域查找for (var j = 0; j < _this.btns.length; j++) {_this.btns[j].className = '';_this.tabs[j].className = '';}//当前点击的这个 li 有active类名this.className = 'active';//让实例身上的tabs里面索引对应的那一个li有active//拿到当前li身上保存的索引var index = this.getAttribute('index') - 0;_this.tabs[index].className = 'active';})}}//使用的时候//选项卡就可以使用了var t = new Tabs('#box')//实例对象在调用方法//函数调用方式,对象.函数名()//函数内部的 this 就是指向 点 前面的 xxx//在change函数里面写的this就是tt.change()console.log(t);//实现第二个选项卡var t2 = new Tabs('#box2');t2.change();//实现第三个选项卡var t3 = new Tabs('#box3');t3.change();</script>
</body></html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/5789.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【学习记录】MindVersion工业摄像头调试

前一阵调试了新到的一大批设备&#xff0c;其中只有工业摄像头没有提供官方的ROS驱动&#xff0c;只有一个官方的SDK&#xff0c;在github上找到了之前师兄写的一个旧版本的ROS驱动&#xff0c;但是调试过程一直显示连接不上摄像头&#xff0c;错误信息类似于下面这样&#xff…

2023深圳杯/东三省A题B题C题数学建模思路代码

本次2023深圳杯数学建模我们会全程提供主供&#xff0c;包括思路代码模型&#xff0c;请关注我们&#xff01; 详情查看文末&#xff01; A题思路&#xff1a; &#xff08;比赛开始后第一时间发布&#xff09; B题思路&#xff1a; &#xff08;比赛开始后第一时间发布&…

C++11:新特性(总结+实例)

C11是C语言的一个重要版本&#xff0c;引入了许多新的特性和语法改进&#xff0c;使得C编程更加方便、高效和安全。下面是一些C11的新特性和实例的详解。 1、自动类型推断&#xff08;auto&#xff09; C11引入了auto关键字&#xff0c;用于自动推断变量的类型。这样可以简化代…

【MySQL】SQL性能分析 (七)

&#x1f697;MySQL学习第七站~ &#x1f6a9;本文已收录至专栏&#xff1a;MySQL通关路 ❤️文末附全文思维导图&#xff0c;感谢各位点赞收藏支持~ 假如我们需要对SQL进行优化&#xff0c;我们就必须对他足够的了解&#xff0c;比如 对哪一类SQL进行优化&#xff08;增删改查…

基于物联网网关的工业数据可视化平台有什么功能?

随着数字化浪潮的不断发展&#xff0c;工业数据的价值越来越重要。在企业利用数据的过程中&#xff0c;数据可视化是数字化系统中十分重要的一部分。然而&#xff0c;工厂多种设备、多种协议影响到系统的搭建使得企业无法获得全面的数据视图&#xff0c;也无法对整个生产流程进…

OJ练习第142题——路径总和 II

113. 路径总和 II 力扣链接&#xff1a;113. 路径总和 II 题目描述 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 Java代码&#xff08;深度优先搜…

六边形架构

六边形架构 微服务系统架构微服务定义微服务系统设计 传统分层架构六边形架构参考资料 微服务系统架构 需求描述做什么的问题&#xff0c;架构描述怎么做的问题(描述组成系统的各部件及其之间的关系) 微服务定义 下面的定义来自周志明老师的 凤凰架构 微服务是一种通过多个小型…

【Linux】 由“进程”过渡到“线程” -- 什么是线程(thread)?

知识引入初识线程1.什么叫做进程&#xff1f;2.什么叫做线程&#xff1f;3.如何看待我们之前学习的进程&#xff1f; 理解线程创建线程函数调用1.线程一旦被创建&#xff0c;几乎所有资源都是被线程所共享的2.与进程之间切换相比&#xff0c;线程的切换 初识线程总结&#xff1…

使用 Docker 快速上手中文版 LLaMA2 开源大模型

本篇文章&#xff0c;我们聊聊如何使用 Docker 容器快速上手朋友团队出品的中文版 LLaMA2 开源大模型&#xff0c;国内第一个真正开源&#xff0c;可以运行、下载、私有部署&#xff0c;并且支持商业使用。 写在前面 感慨于昨天 Meta LLaMA2 模型开放下载之后&#xff0c;Git…

操作系统练习:进程间通信(共享内存方式)

说明 本文是《操作系统概念(第九版)》3.4节“进程间通信”的练习。 进程间通信主要由两种模型&#xff1a; 共享内存消息传递 本文使用共享内存的方式实现进程间的通信 创建消息生产者 创建生产者的主要操作包括&#xff1a; 定义共享内存的大小、名称&#xff0c;以及通…

Pytorch个人学习记录总结 02

目录 Tensorboard Tensorboard 启动tensorboard服务 cd 到 logs 目录所在的同级目录&#xff0c;在命令行输入如下命令&#xff0c;logdir等式右边可以是相对路径或绝对路径。 tensorboard --logdirlogs --port 6006 #如果是Windows环境&#xff0c;要注意路径解析&#xf…

建Stable-Diffusion-Webui的AI

建Stable-Diffusion-Webui的AI 人工智能,丹青圣手,全平台(原生/Docker)构建Stable-Diffusion-Webui的AI绘画库教程(Python3.10/Pytorch1.13.0) - 知乎

netty知识集锦2

粘包半包 粘包半包解决方案&#xff0c; 1短链接&#xff0c;它的消息边界是从链接建立到链接断开 2.定长解码器&#xff1a;服务器端选最大长度的消息作为定长&#xff0c;客户端不足补齐&#xff0c;缺点造成浪费 netty协议设计与解析 Message编码解码

AWS IAM介绍

前言 AWS是世界上最大的云服务提供商&#xff0c;它提供了很多组件供消费者使用&#xff0c;其中进行访问控制的组件叫做IAM(Identity and Access Management)&#xff0c; 用来进行身份验证和对AWS资源的访问控制。 功能 IAM的功能总结来看&#xff0c;主要分两种&#xff1…

《零基础入门学习Python》第060讲:论一只爬虫的自我修养8:正则表达式4

有了前面几节课的准备&#xff0c;我们这一次终于可以真刀真枪的干一场大的了&#xff0c;但是呢&#xff0c;在进行实战之前&#xff0c;我们还要讲讲正则表达式的实用方法和扩展语法&#xff0c;然后再来实战&#xff0c;大家多把持一会啊。 我们先来翻一下文档&#xff1a;…

openGauss学习笔记-17 openGauss 简单数据管理-表达式

文章目录 openGauss学习笔记-17 openGauss 简单数据管理-表达式17.1 简单表达式17.2 条件表达式17.3 子查询表达式17.4 数组表达式17.5 行表达式 openGauss学习笔记-17 openGauss 简单数据管理-表达式 表达式类似一个公式&#xff0c;我们可以将其应用在查询语句中&#xff0c…

25 MFC 数据库

文章目录 导入ADO库 导入ADO库 #import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","rsEOF")void CADODlg::OnBnClickedBtnQuery() {//导入ADO库::CoInitialize(NULL);//初始化COM库_ConnectionPtr pCo…

《面试1v1》如何提高远程用户的吞吐量

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

Flutter动画库:animations(路由过渡动画或者页面切换动画)

animations animations 是一个 Flutter 库&#xff0c;它提供了一组用于创建动画效果的工具和组件。这个库的核心重点是路由过渡动画或者页面切换动画 地址 https://pub-web.flutter-io.cn/packages/animations 安装 flutter pub add animations看了下官方文档和官方例子&a…

计科web常见错误排错【HTTP状态404、导航栏无法点开、字符乱码及前后端数据传输呈现、jsp填写的数据传到数据库显示null、HTTP状态500】

web排错记录 在使用javaweb的过程中会出现的一些错误请在下方目录查找。 目录 错误1&#xff1a;HTTP状态404——未找到 错误2&#xff1a;导航栏下拉菜单无法点开的问题 错误3&#xff1a;字符乱码问题 错误4&#xff1a;jsp网页全部都是&#xff1f;&#xff1f;&#x…