尝试在 Javascript (ES5) 中实现 OPP 继承的简单方法

2024-03-26

只是出于好奇,我在 Javascript 中玩弄原型继承和 OOP 继承。大多数结果涉及用函数模拟“类”和“扩展”概念,而其他结果则使用原型和构造函数。

我写了这段代码:

function Warrior(weaponName) {
    var weapon = weaponName;
    this.getWeapon = function() {
        return weapon;
    };
    this.setWeapon = function(value) {
        weapon = value;
    };
    this.displayInfo = function() {
        return {
            "weapon": this.getWeapon(),
        };
    };
}

function Archer() {
    var accuracy = "86%";
    this.parent = Archer.prototype; // Inheritance workaround
    this.getAccuracy = function() {
        return accuracy;
    };
    this.setAccuracy = function(value) {
        accuracy = value;
    };
    this.displayInfo = function() {
        var form = this.parent.displayInfo();
        form.accuracy = this.getAccuracy();
        return form;
    };
}
Archer.prototype = new Warrior("bow");
var w = new Warrior("sword");
var a = new Archer();
console.log(w.displayInfo());
console.log(a.displayInfo());

我这样做是为了在显示 Warrior 类的信息时,它将对象显示为

{ weapon: "sword" }

而当Archer的信息显示出来时,对象是:

{ weapon: "sword", accuracy: "86%" }

“子类”从“超类”获取信息并添加到其中。从 Archer 调用“getWeapon()”或“setWeapon”也可以。即使我添加了扩展“Archer”并也具有自己的属性的第三类“Kyudoka”,该链仍然可以正常运行。

但与我在研究时发现的更复杂的代码相比,我觉得这可能是一个幼稚的实现(“继承解决方法”行),并且我错过了一些东西(考虑到 JS 有很多微妙之处)。

这是一个理论问题,我没有在任何系统中使用这段代码。


继承主要有3种javascript,根据书Javascript 的优点: 伪古典, 原型 and 功能性.

您刚刚发布的内容将位于伪古典继承,您可以使用构造函数模拟类行为。

我发现更有用和灵活功能性模式,它允许您保护变量(使它们私有)。

var constructor = function (spec, my) {
  var that, other private instance variables;
  my = my || {};
  //Add shared variables and functions to my
  that = a new object;
  //Add privileged methods to that
  return that;
}

原型基本上是让您的对象直接从其他有用的对象继承,这就像将它们(有用的对象)作为您的新对象构造函数原型。

Object.beget = function (o) {
  var F = function () {};
  F.prototype = o;
  return new F();
};

var a = {}
//Add shared variables to a
var b = Object.beget(a);
//Add new methods to b

例如,克罗克福德在他的书中说,每种模式都有很多考虑因素“函数式模式具有很大的灵活性。它比伪经典模式需要更少的努力, 并为我们提供更好的封装和信息隐藏以及对超级方法的访问。”,但我也看到过一些相反的文章,比如这个http://bolinfest.com/javascript/inheritance.php http://bolinfest.com/javascript/inheritance.php

编辑 - - -

如果您可能想了解实现超级方法的不同方法,请在功能性模式,您可以执行以下操作:

Function.prototype.method = function (name, func) {
  this.prototype[name] = func;
  return this;
};

Object.method('superior', function (name) {
  var that = this,
  method = that[name];
  return function ( ) {
    return method.apply(that, arguments);
  };
});

var archer = function (spec, accuracy) {
  var that = warrior(spec),
  super_displayInfo = that.superior('displayInfo');
  that.getAccuracy = function() {
    return accuracy;
  };
  that.setAccuracy = function(value) {
    accuracy = value;
  };
  that.displayInfo = function (n) {
    var form = super_displayInfo()
    form.accuracy = that.getAccuracy();
    return form;
  };
  return that;
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尝试在 Javascript (ES5) 中实现 OPP 继承的简单方法 的相关文章

  • Javascript Firefox - 如果 @import 存在于样式表中,则无法查询 cssRules - bug 或预期行为?

    如果 import 存在于 css 样式表中 我无法查询 cssRules 是否符合网络标准 或者知道 Firefox 的限制 注意 我正在从同一域导入 css 文件 var style rules document styleSheets
  • 如何使用 java/vb 脚本调用自定义 ActiveX dll 中的方法

    我使用 VB6 创建了一个 ActiveX dll 并使用打包和部署向导将其打包 生成了一个 cab 文件和一个演示 HTML 页面 此 ActiveX dll 包含一个 simgle 方法 该方法返回字符串且不接受任何参数 我遇到的麻烦是
  • 从字符串中删除货币符号并使用 Javascript 中的单行转换为数字

    我下面有一个字符串 它是以英镑为单位的价格 我想删除货币符号 然后将其转换为我可以用来与另一个值进行比较的数字 价格 例如 X gt Y 14 50 我之前已将字符串转换为用于货币的数字 var priceNum parseFloat pr
  • javascript获取上周的第一天和最后一天[重复]

    这个问题在这里已经有答案了 我想用 javascript 获取上周的第一天 星期一 和最后一天 星期日 我已经检查过其他主题 但它不起作用 我还需要处理前一周是否是两个不同的月份 我正在使用此代码 但最后一个星期日是 06 03 2014
  • 如何从类外部更改公共 R6 类方法?

    我希望能够在我的 R6 类中重新定义公共方法 以便它根据该类保存的数据类型进行更改 如下所示 library R6 Simple lt R6Class Simple public list dt mtcars my print functi
  • Jquery 动画与 CSS 浮动

    我的代码有问题 宽度似乎可以工作 但浮动没有 这里是 这是一个例子 http jsfiddle net v82ck http jsfiddle net v82ck 问题 悬停时菜单上的浮动属性不会改变 我希望每个菜单元素下方的线在悬停该菜单
  • 对 JavaScript 中的 while 循环感到困惑

    我可能在这里有点厚重 但请回答我这个问题 考虑以下代码 a 1 while a lt 6 console log a a 如果我运行这个 我会在控制台中得到从 1 到 6 的值 然后是另一个 6 现在看看这个 a 1 while a lt
  • 如何在不实例化一个类的情况下检查它是否继承了另一个类? [复制]

    这个问题在这里已经有答案了 假设我有一个如下所示的类 class Derived some inheritance stuff here 我想在我的代码中检查类似的内容 Derived is SomeType 但看起来像is运算符需要 De
  • 在 AngularJS 中覆盖运行时的依赖关系

    我有一个服务叫 doggedHttp 它公开了与 http 现在我想创建一个 doggedResource服务是有角度的 resource服务之上 doggedHttp代替 http 换句话说我想注入 doggedHttp as the h
  • Angular 2 最终版本路由器单元测试

    如何使用 karma 和 jasmine 对 Angular 2 0 0 版中的路由器进行单元测试 这是我的旧单元测试在版本 2 0 0 beta 14 中的样子 import it inject injectAsync beforeEac
  • 嵌套对象的 AJV 模式验证

    函数返回的对象看起来像这样 answer vehicle type 1 message Car model VW color red 答案 对象始终存在 其他字段基于 vehicle type E g 如果vehicle type 1 则有
  • Backbone-relational 无法实例化两个 RelationalModel 对象

    我正在尝试实现 BackboneRelational 并不断获得 无法实例化多个 Backbone RelationalModel 每种类型都有相同的 ID class App Models User extends Backbone Re
  • 如何获取调用函数的“this”值?

    如果我有一个这样的函数 function foo this console log this function bar bar prototype func function foo this var test new bar test f
  • 如何最好地实现多个重叠元素的翻转和推出事件?

    Problem 我正在开发一个网站 其中有一个 拨号盘 显示代表伞式公司不同部门的多个选项卡 目前我已经用 HTML CSS 准备好了一切 每个选项卡的定位 内圈处于较高位置z index因为选项卡在滚动时需要向外动画 我可以实现这部分 选
  • 获取键盘事件中的鼠标位置

    我试图在用户按住 Shift 键时出现选择轮 滚轮应以鼠标位置为中心 然而当我测试这个时 pageX and clientX两者在事件对象上都未定义 是否可以通过键盘事件获取鼠标坐标 不 只需跟踪mousemove事件并持续保存当前位置 以
  • Rails - 使链接与 ajax 一起工作

    我有一个链接 应该使用 ajax 加载它旁边的部分内容 而无需重新加载页面 链接在这里 这是链接应该转到的控制器 class ProfilesController lt ApplicationController def profile f
  • 如何检查摘要周期是否稳定(又名“Angular 完成编译了吗?”)

    tl dr 最初的问题是 如何在每个摘要周期触发回调 但潜在的问题更有趣 因为这回答了两个问题 所以我继续修改了标题 Context 在解决了所有依赖项 nginclude API 调用等之后 我试图控制 Angular 何时完成 HTML
  • 如何修复 AJAX 在选中复选框时始终触发?

    有时这个 AJAX 会触发 有时不会 让我解释一下 habit js document ready function habit check change function habit this parent siblings habit
  • 如何逐步绘制矢量路径? (拉斐尔.js)

    如何逐步动画化矢量路径 就像它被绘制一样 换句话说 慢慢地逐像素地显示路径 我在用着Rapha l js but如果您的答案不是特定于库的 例如可能有一些通用的编程模式可以完成此类事情 我对矢量动画相当陌生 欢迎 使用直线路径很容易做到 就
  • 将元素添加到 D3 圆包节点

    我正在尝试制作一个可缩放的圆形包装图 我希望每个子圆圈包含一个较小的图表 该图表始终具有相同的结构 即 4 列 只有条形的高度会改变 我尝试添加一个简单的rect到目前为止我的图表 但矩形没有添加到圆圈中并且是静态的 JS var marg

随机推荐

  • 如何在 JavaScript 中获取查询字符串值?

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 有没有一种无插件的检索方式请求参数 http en wikipedia org wiki
  • 在 BottomSheetDialog 内的 Viewpager 内嵌套滚动

    简洁版本 我该如何设置NestedScrollingChild of a NestedScrollingParent有多个这样的孩子 长版 我实现了一个BottomSheetDialogFragment其布局由ViewPager 这个vie
  • Delphi 窗口在自定义拖动后失去焦点

    我有这段代码 当我拖动时可以移动我的主窗口MyThingThatDragsIt procedure TMainForm ApplicationMessage var Msg TMsg var Handled Boolean var Scre
  • 查找已选中复选框的顺序

    我正在尝试获取已选中的复选框的顺序 ul class dropdown content checkboxes li li ul
  • 使用cURL上传POST数据和文件

    我想使用 cURL 不仅在 HTTP POST 中发送数据参数 而且还上传具有特定表单名称的文件 我该怎么做呢 HTTP Post 参数 用户 ID 12345 filecomment 这是一个图像文件 HTTP 文件上传 文件位置 hom
  • 在 shell 中生成带有一个特殊字符的随机密码

    我有以下代码 urandom tr dc A Za z0 9 head c 16 这是完美地随机生成密码 我想要两个改变 它只能包含上面列出的一个特殊字符 它应该选择一个随机长度 我尝试过length RANDOM 8 9 然后将长度设置为
  • Android/Firebase - 解析 GCM 事件中的时间戳时出错 - 空时间戳

    我正在构建一个将接收推送通知的 Android 应用程序 我已经完成了 Firebase Cloud Messaging 设置并且几乎可以正常工作 这样我就可以将以下有效负载发送到有效令牌并接收通知和数据 使用网址https fcm goo
  • 本地安装jupyter后,无法运行jupyter笔记本

    在 Linux 红帽上 我尝试在本地安装jupyter pip install jupyter user 似乎一切都安装正确 但是 我不能小跑Jupyter笔记本 nor local bin jupyter 笔记本 Why 安装 pip i
  • 在 Android 上从浏览器下载文件时遇到问题

    我正在使用我的 Galaxy S5 测试正在开发的网站 我们的应用程序在 AWS S3 上公开文件以使用签名 URL 进行下载 下载在内置浏览器和 Chrome 中失败 但在 Firefox 中可以运行 它也可以在我们测试过的所有其他平台上
  • IVpnManagementAgent的IID在哪里定义

    我正在尝试创建一个对象IVpnManagementAgent但我似乎找不到 IID IID x ABI CWindows CNetworking CVpn CIVpnManagementAgent 它的定义是这样我可以实例化RoGetAct
  • “POCO”定义

    有人可以定义 POCO 到底是什么意思吗 我越来越频繁地遇到这个术语 我想知道它是否仅与普通类有关还是意味着更多 普通的旧 C 对象 只是一个普通的类 没有描述基础结构问题的属性或域对象不应具有的其他职责 编辑 正如其他答案所述 它在技术上
  • 隐式类型与匿名类型

    隐式类型和匿名类型之间是否相同或有什么区别 如果不同 那么隐式类型和匿名类型之间的主要区别是什么 这是个很大的差异 隐式类型 局部 变量是未显式给出类型的变量 var i new StringBuilder Now i是隐式类型String
  • 如果未选择所需的输入,则会发出警告

    如何添加警告 printpage当它被禁用时 如果它选择说请检查必填字段 Set up a blur event handler for each text field form control not BusinessName on bl
  • 如何打乱数组以使所有元素改变其位置

    我需要对数组进行洗牌 以便所有数组元素都应该更改其位置 给定一个数组 0 1 2 3 就可以得到 1 0 3 2 or 3 2 0 1 但不是 3 1 2 0 因为2保持不变 我想算法不会是特定于语言的 但以防万一 我在 C 程序中需要它
  • nltk 无法找到 mace4

    在执行下面的代码时 我收到了如上所述的错误 我从以下位置下载了所需的包http www cs unm edu mccune prover9 download http www cs unm edu mccune prover9 downlo
  • 翻译字符串作为 Laravel 中的键

    我阅读了有关翻译字符串的文档检索翻译字符串 https laravel com docs 5 4 localization retrieving translation strings但不知何故我不明白如何应用它 假设我想在视图中渲染pos
  • 使UIImage符合NSCopying协议

    问题很简单 我需要一个符合 NSCopying 协议的 UIImage 但我完全不知道从哪里开始实现这一点 你有什么指示可以帮助我吗 提前致谢 id copyWithZone NSZone zone return UIImage alloc
  • SQL方法用单个空格替换重复空格

    有没有更优雅的方法来做到这一点 我想用单个空格替换重复的空格 declare i int set i 0 while i lt 20 begin update myTable set myTextColumn replace myTextC
  • 使用路径样式 amazon aws sdk go

    我在我的应用程序中使用一些 aws sdk go 功能 它会创建要请求的 DNS 样式主机 例如somebucket mys3 com 但我有一些 DNS 问题 希望以路径方式接收请求 例如mys3 com somebucket 如何配置
  • 尝试在 Javascript (ES5) 中实现 OPP 继承的简单方法

    只是出于好奇 我在 Javascript 中玩弄原型继承和 OOP 继承 大多数结果涉及用函数模拟 类 和 扩展 概念 而其他结果则使用原型和构造函数 我写了这段代码 function Warrior weaponName var weap