JavaScript基础3之面向对象关于面向过程、函数式编程、对比、构造函数、原型

JavaScript基础

  • 面向对象
    • 面向过程
    • 函数式编程
      • 命令式编程
      • 函数式编程
        • 特性
          • 副作用
          • 透明引用
          • 不可变变量
          • 函数是一等公民
        • 常见的函数式编程模型
    • 面向对象
      • 为什么要使用面向对象
        • 封装
        • 继承
        • 多态
    • 对比
      • 面向过程
      • 函数式编程
      • 面向对象
  • 构造函数
  • 原型
    • constructor
      • 使用场景
    • 对象原型

面向对象

面向过程

按照我们分析好了的步骤,按照步骤解决问题
步骤:函数
函数的调用

函数式编程

编写程序的方法论
利用函数把运算结果包装,
复杂的功能,可以通过组合各种函数计算结果

命令式编程

例如:对数组每一个数字平方变化

var arr = [0,1,2,3,4]
for (let i = 0; i < arr.length; i++) {arr[i]= Math.pow(arr[i],2)
}

命令式编程
可读性不强 变量声明多。很难排查

函数式编程

[0,1, 2, 3, 4].map(num ⇒ Math.pow(num,2))

通过函数对数据进行转换

特定:

  • 通过函数对数据进行转换
  • 通过串联多个函数来求结果
特性
副作用
//有副作用 修改了外部变量a
var a =1
function test1() {a++return a
}// 无副作用 没有修改外部状态
// 多次调用结果都是一样的
function test2(a){
return a +1
}
透明引用
// 有副作用 修改了外部变量a
// 函数内容使用的变量并不属于他的作用域
var a =1
var b =2
function test1() {
return a + b
}// 无副作用 没有修改外部状态
// 多次调用结果都是一样的
// 函数内部使用的变量是显式传参方式
function test2(a,b){
return a + b
}
不可变变量

指的是一个变量一旦创建后,就不能再进行修改,任何修改都会生成一个新的变量

var obj = Immutable({ a: 1 });
var obj2 = obj.set('a', 2);
console.log(obj);  // Immutable({ a: 1 })
console.log(obj2); // Immutable({ a: 2 })
函数是一等公民

指的是函数与其他数据类型一样,处于平等地位,
可以赋值给其他变量,也可以作为参数,传入另一个函数,
或者作为别的函数的返回值

常见的函数式编程模型
  • 闭包
  • 高阶函数
    - map
    - filter
    - reduce
  • 函数柯里化
  • 函数组合

面向对象

面向对象也是一种开发模型,主要围绕着数据或者对象而不是功能和逻辑来组织代码
他让开发者的关注点由逻辑转为想要操纵的数据,他将数据和方法都包装在一个类中
这样有利于代码的重用和可扩展性。

class Person{constructor(name) {this.name=name}say(){console.log("我叫:"+this.nane)}
}let person1=new Person("张三")
let person2=new Person("李四")

为什么要使用面向对象

面向对象是以对象功能来划分问题,而不是步骤

  • 面向对象程序开发思想中,每一个对象都是功能中心,具有明确的分工
  • 面试对象编程具有灵活性、代码可复用、容易维护和开发的优点,更合适多人合作的大型软件项目
  • 面向对象三大特点:封装、继承、多态
封装

所有的数据和方法都被封装在对象内,由开发者自己选择性的去公开哪些属性和方法,对于创建的实例来说他能访问的只能是这些公开的属性和方法,而对于其他对象来说是无权访问此类或者进行更改,封装这一特性为程序提供了更高的安全性。

继承

继承意味着代码的可重用性,子类和父类这两个概念就是很好的体现,子类拥有父类所有的属性和方法避免数据和方法的重复定义,同时也能够保持独特的层析结构,

多态

多态意味着设计对象以共享行为,使用继承子类可以用新的方法去覆盖父类共享的行为,多态性允许同一个方法执行两种不同的行为:覆盖和重载。

对比

面向过程

优点:性能比面向对象高,适合跟硬件联系很紧密的东西,例如单片机就采用面向过程编程
缺点:没有面向对象易维护、易复用、易扩展

函数式编程

优点:代码简洁,易于理解,并发速度快使用 immutable 数据管理方式可以避免掉很多情况的 lock,并发处理速度会很快。出错率少
缺点:性能消耗大、资源占用大

面向对象

优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护
缺点:状态的共享、耗内存、性能低

构造函数

用来创建对象
Object Array 原生构造函数

new Object()
new Array()
function Person(name,age){this.name=namethis.age=agethis.sayName =function (){console.log(this.name,this.age)}
}//实例
let person1=new Person("张三",18)
let person2=new Person("李四",25)person1.sayName()
person2.sayName()console.log(person1 === person2)
console.log(person1.sayName===person2.sayName)

在这里插入图片描述
通过this实现数据的共享
不同的是通过构造函数创建出的实例对象他们之间彼此是不影响的

  • 构造函数体现了面向对象的封装
  • 构造函数实例对象彼此是互不影响的

存在浪费内存的问题

试图解决一下:

function Person(name, age) {this.name = name;this.age = age;this.sayName = sayName
}function sayName() {console.log(this.name);
}let person1 = new Person('小明', 18)
let person2 = new Person('小红', 20)person1.sayName() // 小明
person2.sayName() // 小红

虽然解决了相同逻辑的函数重复定义的问题,但全局作用域也因此被搞乱了,因为那个函数实际上只能在一个对象上调用。如果这个对象需要多个方法,那么就要在全局作用域中定义多个函数。这会导致自定义类型引用的代码不能很好地聚集一起。这个新问题可以通过原型模式来解决。

原型

目的:能够利用原型对象实现方法共享

  • 构造函数通过原型分配的函数是所有对象所共享的
  • 每个函数都会创建一个 prototype 属性,这个属性是一个对象,称为原型对象
  • 原型对象可以挂载函数,对象实例化不会多次创建原型函数,节约内存
  • 可以把那些不变的方法,直接定义在原型对象上面,定义的属性和方法可以被对象实例共享
  • 构造函数和原型对象中的this都指向实例化的对象
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<script>function Person(name,age){this.name=namethis.age=agePerson.prototype.sayName=function(){console.log(`我叫${this.name},今年${this.age}岁了`)}}//实例let person1=new Person("张三",18)let person2=new Person("李四",25)person1.sayName()person2.sayName()console.log(person1 === person2)console.log(person1.sayName===person2.sayName)console.dir(Person)
</script>
</body>
</html>

在这里插入图片描述

constructor

默认情况下,所有原型对象自动获得一个名为 constructor 的属性,
作用:该属性指向该原型对象的构造函数
对前面的例子而言,Person.prototype.constructor 指向 Person

原型对象上面默认只会获取constructor属性,其他的所有方法都继承Object

在这里插入图片描述
也可以这样理解
在这里插入图片描述
简单理解来说:
在这里插入图片描述

使用场景

下面这段代码相当于将prototype原型对象重新赋值了,替换掉了默认的constructor函数,所以为了代码的完整性,还要加上constructor:Person这一行

Person.prototype={sayName(){},...
}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<script>function Person(name,age) {this.name = namethis.age = age}//Person.prototype本身是一个对象,所以直接复用//相当于Person.prototype=new Object() === Person.prototype={}//此时constructor就是挂载到Object上的,Person.prototype={constructor:Person,  //如果没有这一行代码,此时constructor就是挂载到Object上的,因此改变constructor的挂载,挂载到Person上sayName(){console.log(`我叫:${this.name}`)},sing(){console.log("唱歌")},dance(){console.log("跳舞")}}//实例let person1=new Person("张三",18)let person2=new Person("李四",25)person1.sayName()person2.sayName()person1.sing()person2.dance()console.dir(Person)
</script>
</body>
</html>

在这里插入图片描述

对象原型

构造函数可以创建实例对象,构造函数还有一个原型对象,一些公共的属性或者方法放到这个原型对象身上
但是为啥实例对象可以访问原型对象里面的属性和方法呢?
在这里插入图片描述
对象都会有一个属性__proto__指向构造函数的prototype原型对象,之所以我们对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto__原型的存在。
在这里插入图片描述

new 构造函数 => 实例
[[prototype]] → 构造函数的原型对象 prototype

每次调用构造函数创建一个新实例,这个实例的内部[[Prototype]]指针就会被赋值为构造函数的原型对象,脚本中没有访问这个[[Prototype]]特性的标准方式,但 Firefox、Safari 和 Chrome会在每个对象上暴露__proto__属性,通过这个属性可以访问对象的原型

所以,我们对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto__原型的存在
对象原型指向原型对象
在这里插入图片描述

function Person() {
}console.log(typeof Person.prototype)let person = new Person()
let person2 = new Person()
console.log(person.__proto__ === Person.prototype) // true
console.log(person.__proto__.constructor === Person) // true
console.log(person.__proto__ === person2.__proto__) // true

正常的原型链都会终止于 Object 的原型对象,Object 原型的原型是 null

console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Person.prototype.__proto__.constructor === Object); // true
console.log(Person.prototype.__proto__.__proto__ === null); // true
console.log(Person.prototype.__proto__);
{constructor: ƒ Object()hasOwnProperty: ƒ hasOwnProperty()isPrototypeOf: ƒ isPrototypeOf()propertyIsEnumerable: ƒ propertyIsEnumerable()toLocaleString: ƒ toLocaleString()toString: ƒ toString()valueOf: ƒ valueOf()
}

请添加图片描述

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

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

相关文章

chrome自动更新后,手动恢复书签和历史记录

本文是针对google没有登录账号信息&#xff0c;浏览器更新后&#xff0c;如何恢复本地书签可历史记录。 为了解决“已被CORS策略阻止&#xff1a;请求的资源上没有’Access-Control-Allow-Origin’标头&#xff08;跨域请求失败”这个问题&#xff0c;修改了Google属性&#x…

android开发教程视频,android组件化和插件化

第一阶段&#xff1a;Android 基础知识回顾&#xff1a; 回顾Android 开发编程&#xff0c;深入理解Android系统原理和层次结构&#xff0c;深入分析Handler源码和原理&#xff1b;回顾Java&#xff0c;C/C&#xff0c;Kotlin、dart 在Android开发中必用的语言&#xff0c;熟悉…

算法学习03:前缀和与差分(互逆)

算法学习03&#xff1a;前缀和与差分&#xff08;互逆&#xff09; 文章目录 算法学习03&#xff1a;前缀和与差分&#xff08;互逆&#xff09;前言一、前缀和1.一维2.二维 二、差分1.一维在这里插入图片描述2.二维在这里插入图片描述 ![在这里插入图片描述](https://img-blog…

LeetCode 2368.受限条件下可到达节点的数目:搜索 + 哈希表

【LetMeFly】2368.受限条件下可到达节点的数目&#xff1a;搜索 哈希表 力扣题目链接&#xff1a;https://leetcode.cn/problems/reachable-nodes-with-restrictions/ 现有一棵由 n 个节点组成的无向树&#xff0c;节点编号从 0 到 n - 1 &#xff0c;共有 n - 1 条边。 给…

H3C接入交换机收到大量上行口(连接汇聚交换机)TC报文该怎么处理?(排查思路及解决办法)

一、问题描述 H3C接入交换机收到大量上行口的TC报文。 二、告警信息 三、TC报文排查思路 1、检查物理链路是否有问题。 2、检查是否有可能存在环路。 3、终端接入的端口开启STP边缘端口。 4、根桥的下联端口开启STP根保护。 5、如果对端设备不是管辖的范围且无法管理到,可考虑…

如何管理系统中的敏感数据?

如何管理系统中的敏感数据&#xff1f; 本文转自 公众号 ByteByteGo&#xff0c;如有侵权&#xff0c;请联系&#xff0c;立即删除 如何在系统中管理敏感数据&#xff1f;下图列出了一系列指导原则。 什么是敏感数据&#xff1f; 个人身份信息 (PII)、健康信息、知识产权、财务…

STM32标准库——(17)硬件SPI读写W25Q64

1.SPI外设简介 时钟频率就是sck波形的频率&#xff0c;一个sck时钟交换一个bit&#xff0c;所以时钟频率一般体现的是传输速度&#xff0c;单位是Hz或者bit/s&#xff0c;那这里的时钟频率是fPCLK除以一个分频系数&#xff0c;分频系数可以配置为2或4或8、16、32、64、128、256…

输出X^N对233333取模的结果。

对任意正整数N&#xff0c;求XN%233333的值。 要求运算的时间复杂度为O(logN)。 例如X30 X15*X15X15X7*X7*XX7X3*X3*XX3X*X*X共7次乘法运算完毕。输入输出格式 输入描述: 输入两个整数X和N&#xff0c;用空格隔开&#xff0c;其中X,N<10^9。 输出描述: 输出X^N对233333取模…

STL容器之map和set的补充AVL树

一、AVL树 ​ 不同搜索的对比&#xff1a;1.暴力搜索时间复杂度是O(N)&#xff1b;2.二分查找的时间复杂度是O(lgN)&#xff0c;但是伴随着有序&#xff0c;插入删除挪动数据的成本极高&#xff1b;3.二叉搜索的时间复杂度是高度次数&#xff0c;极端场景会退化为类似链表时间…

【送书活动1】基于React低代码平台开发:构建高效、灵活的应用新范式

【送书活动1】基于React低代码平台开发&#xff1a;构建高效、灵活的应用新范式 写在最前面一、React与低代码平台的结合优势二、基于React的低代码平台开发挑战三、基于React的低代码平台开发实践四、未来展望《低代码平台开发实践&#xff1a;基于React》编辑推荐内容简介作者…

基于springboot实现的学生评奖评优管理系统的设计与实现(源码|论文)

系统概述 springboot实现的学生评奖评优管理系统的设计与实现&#xff0c;系统分Web端和后台管理端&#xff0c;后端采用的是springbootmybatis&#xff0c;前端采用vuehtml&#xff0c;代码简洁易懂&#xff0c;有配套论文初稿&#xff0c;适合新手小白学变编程... 一、系统架…

RocketMQ—RocketMQ集成SpringBoot

RocketMQ—RocketMQ集成SpringBoot 新建生产者的boot项目和消费者的boot项目&#xff0c;pom文件重点如下&#xff1a; <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</arti…

Docker中使用nginx-rtmp推拉网络摄像头视频流

前言&#xff1a; 该部分比较麻烦&#xff0c;闹腾了好久&#xff08;ffmpeg推拉流没学过&#xff0c;事实证明依葫芦画瓢是不行滴&#xff0c;后面有时间再学吧&#xff09;&#xff0c;后来借助chatGPT勉强解决&#xff0c;但不是很懂。因个人能力有限&#xff0c;只复述操作…

Starknet(strk) 跨链桥教程:手把手教你用bitget钱包跨链

摘要&#xff1a;通过Rhino.fi &#xff0c;将资产无缝桥接至Starknet&#xff08;web3.bitget.com/zh/assets/starknet-wallet&#xff09;变得高效且具有成本效益&#xff0c;Rhino.fi 是一个以其快速处理时间和低交易费用而闻名的平台。它专为与 MetaMask 等流行的 Web 3 钱…

长整数拼接后求余数

原题&#xff1a;2024牛客寒假算法基础集训营3 M题 方法一&#xff1a; 用递归进行长整数除法&#xff0c;暴力寻找&#xff0c;但是会超时 #include <bits/stdc.h> using namespace std; bool f(string &s, int ans,int count) {if (count > s.size()) {if (a…

Newsmy储能电源与您相约九州汽车生态博览

2024年3月7日—10日&#xff0c;第24届 深圳国际智慧出行、汽车改装及汽车服务业态博览会&#xff08;以下简称“九州汽车生态博览会”&#xff09;将在深圳国际会展中心&#xff08;宝安&#xff09;举办&#xff0c;Newsmy纽曼集团将在3号馆32523展位&#xff0c;携全系产品与…

2024年3月6日 十二生肖 今日运势

小运播报&#xff1a;2024年3月6日&#xff0c;星期三&#xff0c;农历正月廿六 &#xff08;甲辰年丁卯月己巳日&#xff09;&#xff0c;法定工作日。 红榜生肖&#xff1a;牛、猴、鸡 需要注意&#xff1a;鼠、虎、猪 喜神方位&#xff1a;东北方 财神方位&#xff1a;正…

nginx 常见面面问题

1.什么是 Nginx&#xff1f; Nginx 是一个 轻量级 / 高性能的反向代理 Web 服务器&#xff0c;用于 HTTP、HTTPS、SMTP、POP3 和 IMAP 协议。他实现非常高效的反向代理、负载平衡&#xff0c;他可以处理 2-3 万并发连接数&#xff0c;官方监测能支持 5 万并发&#xff0c;现在中…

Java毕业设计 基于SpringBoot 众筹网

Java毕业设计 基于SpringBoot 众筹网 SpringBoot 众筹网 功能介绍 注册 邮箱验证码 登录 忘记密码 首页 图片轮播 关于我们 项目列表 发布项目 我的添加项目 提交审核 已在募捐 项目详情 项目介绍 项目进展 捐赠列表 评论 新闻列表 发布新闻 新闻详情 评论新闻 联系我们 提交…

Linux笔记--静态库和动态库

库是指在我们的应用中&#xff0c;有一些公共代码是需要反复使用&#xff0c;就把这些代码编译为"库"文件;在链接步骤中&#xff0c;链接器将从库文件取得所需的代码&#xff0c;复制到生成的可执行文件中。 Linux中常见的库文件有两种&#xff0c;一种.a为后缀&…