JavaScript高级程序设计(第四版)--学习记录之对象、类和面向对象编程(中)

创建对象方式

工厂模式:用于抽象创建特定对象的过程。可以解决创建多个类似对象的问题,但没有解决对象标识问题。(即新创建的对象是什么类型)

function createPerson(name, age, job) { 
 let o = new Object(); 
 o.name = name; 
 o.age = age; 
 o.job = job; 
 o.sayName = function() { 
 console.log(this.name); 
 }; 
 return o; 
} 
let person1 = createPerson("Nicholas", 29, "Software Engineer"); 
let person2 = createPerson("Greg", 27, "Doctor");

构造函数模式:用于创建特定类型对象。构造函数名称的首字母都是要大写的,用来区分非构造函数。

function Person(name, age, job){ 
 this.name = name; 
 this.age = age; 
 this.job = job; 
 this.sayName = function() { 
 console.log(this.name); 
 }; 
} 
let person1 = new Person("Nicholas", 29, "Software Engineer"); 
let person2 = new Person("Greg", 27, "Doctor"); 
person1.sayName(); // Nicholas 
person2.sayName(); // Greg

原型模式:每个函数都会创建一个prototype属性,这个属性是一个对象,包含应该由特定引用类型的实例共享的属性和方法。使用原型对象的好处是,在它上面定义的属性和方法可以被对象实例共享。

function Person() {} 
Person.prototype.name = "Nicholas"; 
Person.prototype.age = 29; 
Person.prototype.job = "Software Engineer"; 
Person.prototype.sayName = function() { 
 console.log(this.name); 
}; 
let person1 = new Person(); 
person1.sayName(); // "Nicholas" 
let person2 = new Person(); 
person2.sayName(); // "Nicholas" 
console.log(person1.sayName == person2.sayName); // true

继承的方式:接口继承和实现继承。接口继承在 ECMAScript 中是不可能的,因为函数没有签名。实现继承是 ECMAScript 唯一支持的继承方式,而这主要是通过原型链实现的。

原型链 

其基本思想就是通过原型继承多个引用类型的属性和方法。
function SuperType() { 
 this.property = true; 
} 
SuperType.prototype.getSuperValue = function() { 
 return this.property; 
}; 
function SubType() { 
 this.subproperty = false; 
} 
// 继承 SuperType 
SubType.prototype = new SuperType(); 
SubType.prototype.getSubValue = function () {
return this.subproperty; 
}; 
let instance = new SubType(); 
console.log(instance.getSuperValue()); // true

原型链虽然是实现继承的强大工具,但它也有问题。问题一:出现在原型中包含引用值的时候。前面在谈到原型的问题时也提到过,原型中包含的引用值会在所有实例间共享,这也是为什么属性通常会在构造函数中定义而不会定义在原型上的原因。在使用原型实现继承时,原型实际上变成了另一个类型的实例。这意味着原先的实例属性摇身一变成为了原型属性。
问题二:子类型在实例化时不能给父类型的构造函数传参。
function SuperType() { 
 this.colors = ["red", "blue", "green"]; 
} 
function SubType() {} 
// 继承 SuperType 
SubType.prototype = new SuperType(); 
let instance1 = new SubType(); 
instance1.colors.push("black"); 
console.log(instance1.colors); // "red,blue,green,black" 
let instance2 = new SubType(); 
console.log(instance2.colors); // "red,blue,green,black"

解决原型包含引用值导致的继承问题

盗用构造函数:在子类构造函数中调用父类构造函数。优点可以在子类构造函数中向父类构造函数传参。缺点:必须在构造函数中定义方法,因此函数不能重用。

function SuperType(name){ 
 this.name = name; 
} 
function SubType() { 
 // 继承 SuperType 并传参
 SuperType.call(this, "Nicholas"); 
 // 实例属性
 this.age = 29; 
} 
let instance = new SubType(); 
console.log(instance.name); // "Nicholas"; 
console.log(instance.age); // 29

 组合继承:综合了原型链和盗用构造函数,使用原型链继承原型上的属性和方法,通过盗用构造函数继承实例属性。

function SuperType(name){ 
 this.name = name; 
 this.colors = ["red", "blue", "green"]; 
} 
SuperType.prototype.sayName = function() { 
 console.log(this.name); 
}; 
function SubType(name, age){ 
 // 继承属性
 SuperType.call(this, name); 
 this.age = age; 
} 
// 继承方法
SubType.prototype = new SuperType(); 
SubType.prototype.sayAge = function() { 
 console.log(this.age); 
}; 
let instance1 = new SubType("Nicholas", 29); 
instance1.colors.push("black"); 
console.log(instance1.colors); // "red,blue,green,black" 
instance1.sayName(); // "Nicholas"; 
instance1.sayAge(); // 29 
let instance2 = new SubType("Greg", 27); 
console.log(instance2.colors); // "red,blue,green" 
instance2.sayName(); // "Greg"; 
instance2.sayAge(); // 27

原型式继承

ES5通过增加 Object.create()方法将原型式继承的概念规范化了,这个方法接收两个

参数:作为新对象原型的对象,以及给新对象定义额外属性的对象(第二个可选)。
原型式继承非常适合不需要单独创建构造函数,但仍然需要在对象间共享信息的场合。
let person = { 
 name: "Nicholas", 
 friends: ["Shelby", "Court", "Van"] 
}; 
let anotherPerson = Object.create(person); 
anotherPerson.name = "Greg"; 
anotherPerson.friends.push("Rob"); 
let yetAnotherPerson = Object.create(person); 
yetAnotherPerson.name = "Linda"; 
yetAnotherPerson.friends.push("Barbie"); 
console.log(person.friends); // "Shelby,Court,Van,Rob,Barbie"

寄生式继承

function createAnother(original){ 
 let clone = object(original); // 通过调用函数创建一个新对象
 clone.sayHi = function() { // 以某种方式增强这个对象
 console.log("hi"); 
 }; 
 return clone; // 返回这个对象
}

寄生式组合继承

function SuperType(name) { 
 this.name = name; 
 this.colors = ["red", "blue", "green"]; 
} 
SuperType.prototype.sayName = function() { 
 console.log(this.name); 
}; 
function SubType(name, age){ 
 SuperType.call(this, name); // 第二次调用 SuperType() 
 this.age = age; 
} 
SubType.prototype = new SuperType(); // 第一次调用 SuperType() 
SubType.prototype.constructor = SubType; 
SubType.prototype.sayAge = function() { 
 console.log(this.age); 
};

寄生式组合继承算是引用类型继承的最佳模式!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

广和通 OpenCPU 二次开发(二) ——通过linux编译

广和通 OpenCPU 二次开发(二) ——通过linux编译 一、编译命令总结 1.编译环境配置 . tools/core_launch.sh cout cmake ../.. -G Ninja 2.编译 ninja 二、命令解释 1. 执行 tools/core_launch.sh 这是一个脚本文件 core_launch.sh,通…

技术赋能政务服务:VR导视与AI客服在政务大厅的创新应用

在数字化转型的浪潮中,政务大厅作为服务民众的前沿阵地,其服务效率和质量直接影响着政府形象和民众满意度。然而,许多政务大厅仍面临着缺乏智能化导航系统的挑战,这不仅增加了群众的办事难度,也降低了服务效率。维小帮…

内核错误定位

内核打印出如下: 在代码目录输入: ./prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gdb kernel/vmlinux 进入gdb 命令模式 输入 l *(rk628_csi_probe0xf0) 能定位到出现问题地方。 最后就…

PLM系统:PLM系统如何重塑产品生命周期管理

PLM系统:重塑产品生命周期管理的未来 在当今快速变化的商业环境中,产品生命周期管理(PLM)系统正逐渐成为企业提升竞争力、加速创新并优化运营流程的关键工具。随着技术的不断进步和市场需求的日益复杂化,传统的手动或…

试用笔记之-汇通窗口颜色显示软件(颜色值可供Delphi编程用)

首先下载汇通窗口颜色显示软件 http://www.htsoft.com.cn/download/wdspy.rar 通过获得句柄颜色,显示Delphi颜色值和HTML颜色值

Python:Pycharm安装指南

三、Pycharm安装指南 在开始之前今天内容之前,将上篇的初体验练习题公布如下: 初体验练习题:输入两个字符,将他们组合后输出。 str1 input("请输入名字:") str2 input("请输入城市:&qu…

Vue iview-ui 被tooltip包裹的标题,点击跳转后,提示框不消失

tooltip包裹的标题,点击跳转后,提示框不消失 就会有这种显示问题 下面这种错误方法不可行,解决办法往下翻 css写得没错,问题出在Javascript当中的 getElementsByClassName(“xxabc”), 这个方法得到的是一个由class&q…

Python | Leetcode Python题解之第213题打家劫舍II

题目: 题解: class Solution:def rob(self, nums: List[int]) -> int:def robRange(start: int, end: int) -> int:first nums[start]second max(nums[start], nums[start 1])for i in range(start 2, end 1):first, second second, max(fi…

PHP基础教程——总结W3school

1、<?php ?> 2、$ 声明变量 3、变量大小写敏感 关键字&#xff08;if、else、echo&#xff09;和用户定义的类、函数大小写不敏感 4、三种注释 // # /* */ 5、echo "<br>"; 换行 6、global(关键字) 函数内访问全局变量 $GLOBALS[index] …

7寸微型FPV无人机技术详解

对于7寸微型FPV&#xff08;First Person View&#xff0c;第一人称视角&#xff09;无人机技术的详解&#xff0c;可以从以下几个方面进行介绍&#xff1a; 一、定义与基本概念 FPV无人机&#xff0c;全称为“第一人称视角无人机”&#xff0c;它利用安装在无人机上的摄像头…

[单master节点k8s部署]19.监控系统构建(四)kube-state-metrics

kube-state-metrics 是一个Kubernetes的附加组件&#xff0c;它通过监听 Kubernetes API 服务器来收集和生成关于 Kubernetes 对象&#xff08;如部署、节点和Pod等&#xff09;的状态的指标。这些指标可供 Prometheus 进行抓取和存储&#xff0c;从而使你能够监控和分析Kubern…

科研绘图系列:R语言STAMP图(STAMP Plot)

介绍 STAMP图(STAMP plot)并非一个广泛认知的、具有特定名称的图表类型,而是可能指在STAMP(Statistical Analysis of Metagenomic Profiles:“STAMP: statistical analysis of taxonomic and functional profiles”)软件使用过程中生成的各种统计和可视化图表的总称。ST…

使用OpenCV对图像进行三角形检测、颜色识别与距离估算【附代码】

文章目录 前言功能概述必要环境一、代码结构1. 参数定义2. 距离估计3. 颜色转换4. 图像处理函数4.1 读取图像和预处理4.2 轮廓检测4.3 过滤面积并检测三角形4.4 提取边框并计算距离 二、效果展示红色三角形绿色三角形蓝色三角形黄色三角形 三、完整代码获取总结 前言 本文将介…

通过 Parallels Desktop 虚拟机安装运行 macOS 15 Sequoia

在 Apple 的 WWDC 24 大会上&#xff0c;macOS Sequoia 15 成为全场热议的焦点。 作为科技爱好者和开发者&#xff0c;我们都迫不及待想要体验这些最新功能。但如果直接把整个 Mac 升级到测试版&#xff0c;可能不太现实&#xff0c;特别是当你需要保持主系统稳定的时候。 幸…

Alpha2:使用深度强化学习挖掘公式化的超额收益因子(附论文及源代码)

原创文章第577篇&#xff0c;专注“AI量化投资、世界运行的规律、个人成长与财富自由"。 今天说说因子挖掘&#xff0c;我们之前交付的Deap遗传算法因子挖掘&#xff0c;大家可以前往温习一下&#xff1a; 源码发布Quantlab4.2&#xff0c;Deap因子挖掘|gplearn做不到的…

小程序分包加载、独立分包、分包预加载等

一、小程序分包加载 小程序的代码通常是由许多页面、组件以及资源等组成&#xff0c;随着小程序功能的增加&#xff0c;代码量也会逐渐增加&#xff0c; 体积过大就会导致用户打开速度变慢&#xff0c;影响用户的使用体验。分包加载是一种小程序优化技术。将小程序不同功能的代…

springboot基础入门2(profile应用)

Profile应用 一、何为Profile二、profile配置方式1.多profile文件方式2.yml多文档方式 三、加载顺序1. file:./config/: 当前项目下的/config目录下2. file:./ &#xff1a;当前项目的根目录3. classpath:/config/:classpath的/config目录4. classpath:/ : classpath的根目录 四…

LabVIEW环境下OCR文字识别的实现策略与挑战解析

引言 在自动化测试领域&#xff0c;OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;技术扮演着重要角色&#xff0c;它能够将图像中的文字转换成机器可编辑的格式。对于使用LabVIEW约5个月&#xff0c;主要进行仪器控制与数据采集的你而言…

什么是T0策略?有没有可以持仓自动做T的策略软件?

​​行情低迷&#xff0c;持仓被套&#xff0c;不想被动等待&#xff1f;长期持股&#xff0c;想要增厚持仓收益&#xff1f;有没有可以自动做T的工具或者策略&#xff1f;日内T0交易&#xff0c;做到降低持仓成本&#xff0c;优化收益预期。 什么是T0策略&#xff1f; 可以提…

知识图谱和 LLM:多跳问答

检索增强生成&#xff08;RAG&#xff09;应用程序通过将外部来源的数据集成到 LLM 中&#xff0c;擅长回答简单的问题。但他们很难回答涉及将相关信息之间的点连接起来的多部分问题。这是因为 RAG 应用程序需要一个数据库&#xff0c;该数据库旨在存储数据&#xff0c;以便轻松…