Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么我不使用Child.prototype = Parent.Prototype而不是Child.prototype =新父();用于Javascript继承?

为什么我不使用Child.prototype = Parent.Prototype而不是Child.prototype =新父();用于Javascript继承?
EN

Stack Overflow用户
提问于 2012-06-18 09:56:05
回答 3查看 1.3K关注 0票数 8

在继承的javascript中,我不理解这种行为,我一直看到它是这样定义的:

代码语言:javascript
运行
AI代码解释
复制
function GameObject(oImg, x, y) {

    this.x = x;
    this.y = y;
    this.img = oImg;

    this.hit = new Object();
    this.hitBox.x = x;
    this.hitBox.y = y;
    this.hitBox.width = oImg.width;
    this.hitBox.height = oImg.height;

}

Spaceship.prototype = new GameObject();
Spaceship.prototype.constructor = Spaceship;

function Spaceship(){
    console.log("instantiate ship");
    GameObject.apply(this, arguments);
    this.vx = 0;
    this.vy = 0;
    this.speed = 3;
    this.friction = 0.94;
}

但就我而言,这几句话:

代码语言:javascript
运行
AI代码解释
复制
    this.hitBox.width = oImg.width;
    this.hitBox.height = oImg.height;

当我在我的飞船构造函数中执行console.log(this)时,我可以看到proto属性被设置为Spaceship而不是GameObject,如果我删除它们,它将被设置为GameObject。

如果我用:

代码语言:javascript
运行
AI代码解释
复制
 Spaceship.prototype = GameObject.prototype;

我对此不再有意见了。这阻碍我的原因是,我有另一个带有add()方法的对象,它用以下代码检查GameObject的对象惰性:

代码语言:javascript
运行
AI代码解释
复制
 if(object instanceof GameObject)

我不明白这两行可能会改变什么,这样当继承出现时,继承就会中断,而且我也不确定如何进行继承,第二种方式是好的。有人能告诉我这件事吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-06-18 09:59:21

如果你这样做了

Spaceship.prototype = GameObject.prototype;

然后,它们都引用相同的对象,所以您最好在GameObject中包含所有内容,如果向Spaceship.prototype添加一些内容,那么它也将添加到GameObject.prototype中。您可以通过在赋值后向Spaceship.prototype添加一些内容来轻松地测试它。For example, in your case you can see that GameObject.prototype.constructor is actually Spaceship

至于

代码语言:javascript
运行
AI代码解释
复制
Spaceship.prototype = new GameObject();

这会调用可能产生意外副作用的构造函数,您最好使用:

代码语言:javascript
运行
AI代码解释
复制
Spaceship.prototype = Object.create(GameObject.prototype);

这里使用的Object.create功能可以归结为:

代码语言:javascript
运行
AI代码解释
复制
Object.create = function( proto ) {
    function f(){}
    f.prototype = proto;
    return new f;
};

不过,现代浏览器已经具备了这一功能。

票数 14
EN

Stack Overflow用户

发布于 2015-01-17 13:14:01

从来没有人恰当地解释过为什么你在this.hitBox上会有奇怪的行为(我认为这就是你想说的)。

如果通过调用父构造函数创建原型来进行继承,则只执行该父构造函数一次以创建父类型的实例,然后该子类型的所有实例将共享该一个实例作为它们的原型。

这方面的问题是,如果构造函数有任何将可变对象分配给this的行,那么这些对象将是该原型上的属性,对这些对象的任何修改都将反映在子类型的所有实例中:

代码语言:javascript
运行
AI代码解释
复制
Spaceship.prototype = new GameObject();
Spaceship.prototype.constructor = Spaceship;

var sps1 = new Spaceship();
var sps2 = new Spaceship();

sps1.hitBox.x = 9;
sps2.hitBox.x = 12;
console.log(sps1.hitBox.x);  // 12   (oh noes! what happened)
console.log(sps2.hitBox.x);  // 12

(“调用构造函数以生成原型”方法还有其他类似的问题,但我将把它留在这里。)

@Esailija建议使用Object.create(baseObject)是解决这个问题的第一步。它创建了一个原型为baseObject的新对象,但没有构造函数中设置的内容(这是一件好事,但它需要考虑。继续读下去。)

正如我刚才所说,这将创建一个对象,其中父构造函数中的初始化逻辑从未运行过,但在大多数情况下,该逻辑与对象的功能相关。因此,还需要做一件事,即让子构造函数调用父构造函数:

代码语言:javascript
运行
AI代码解释
复制
function Spaceship(oImg, x, y) {
    // call parent constructor on this object and pass in arguments.
    // you could also use default values for the arguments when applicable
    GameObject.call(this, oImg, x, y);

    // remainder of Spaceship constructor...
}

这将确保父构造函数逻辑为每个新Spaceship分别运行,并执行必要的初始化任务。

票数 2
EN

Stack Overflow用户

发布于 2015-05-23 07:53:37

代码语言:javascript
运行
AI代码解释
复制
function GameObject(oImg, x, y) {

    this.x = x;
    this.y = y;
    this.img = oImg || {width:null, height: null};

    this.hitBox = new Object();
    this.hitBox.x = x;
    this.hitBox.y = y;
    this.hitBox.width = this.img.width;
    this.hitBox.height = this.img.height;

}


function Spaceship(){
    GameObject.apply(this, arguments);
    this.vx = 0;
    this.vy = 0;
    this.speed = 3;
    this.friction = 0.94;
}
Spaceship.prototype = new GameObject();

var sps1 = new Spaceship();
var sps2 = new Spaceship();

sps1.hitBox.x = 9;
sps2.hitBox.x = 12;
console.log(sps1.hitBox.x);  // 9
console.log(sps2.hitBox.x);  // 12
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11088365

复制
相关文章
【计算理论】计算理论总结 ( 上下文无关文法 ) ★★
: 有限的规则组成的集合 , 规则规定如何进行代换操作 , 规定 变量 , 终端字符 , 字符串变量 等 ;
韩曙亮
2023/03/28
8300
【计算理论】计算理论总结 ( 上下文无关文法 ) ★★
上下文无关文法产生的语言都可以用正则文法来描述_c语言结构体默认值
正则表达式只能使用终结符(字母表中的字符),因而很容易变得复杂又难懂,实际中,经常使用正则描述,正则描述允许使用非终结符定义表达式,很像EBNF,但是它限制在未完全定义之前,不能使用非终结符,也就是说不允许递归或自嵌套。
全栈程序员站长
2022/11/01
1.1K0
【计算理论】计算理论总结 ( 上下文无关文法 CFG 转为下推自动机 PDA 示例 2 ) ★★
状态的指令都是从本状态指向本状态 , 生成两种指令 , 一种是基本指令 , 一种是终端字符指令 ;
韩曙亮
2023/03/28
8990
【计算理论】计算理论总结 ( 上下文无关文法 CFG 转为下推自动机 PDA 示例 2 ) ★★
【计算理论】计算理论总结 ( 上下文无关文法 CFG 转为下推自动机 PDA 示例 1 ) ★★
状态的指令都是从本状态指向本状态 , 生成两种指令 , 一种是基本指令 , 一种是终端字符指令 ;
韩曙亮
2023/03/28
9470
【计算理论】计算理论总结 ( 上下文无关文法 CFG 转为下推自动机 PDA 示例 1 ) ★★
【计算理论】计算理论总结 ( 上下文无关文法 | 乔姆斯基范式 | 乔姆斯基范式转化步骤 | 示例 ) ★★
② 语言不包含空字符串 : 如果上下文无关语法不包含空字符串时 , 一定 不需要
韩曙亮
2023/03/28
1K0
【计算理论】上下文无关语法 CFG ( CFG 设计示例 | CFG 歧义性 | Chomsky 范式 | 上下文无关语法 转为 Chomsky 范式 )
2 . 设计方法 : 非确定性优先自动机 ( NFA ) 识别某语言 , 将 NFA 转为 确定性优先自动机 ( DFA ) , 然后将 DFA 转为 上下文无关语法 ;
韩曙亮
2023/03/27
1.3K0
【计算理论】上下文无关语法 CFG ( CFG 设计示例 | CFG 歧义性 | Chomsky 范式 | 上下文无关语法 转为 Chomsky 范式 )
【计算理论】计算理论总结 ( 下推自动机计算过程 | 上下文无关文法 CFG 转为下推自动机 PDA ) ★★
1 . 下推自动机 ( PDA ) 提升了自动机计算能力 : 在上述自动机的基础上 , 提升该自动机的计算能力 , 引入一个新的栈结构 ;
韩曙亮
2023/03/28
8660
大学课程 | 编译原理知识点
令 X 为一个文法符号(一个终结符或非终结符)或 ε ,则集合 First (X) 由终结符组成,此外可能还有 ε ,它的定义如下:
Justlovesmile
2021/12/14
1.3K0
大学课程 | 编译原理知识点
懂前端的你也可以轻松定义自己业务的DSL
jison是一个 JavaScript 编写的解析器生成器,可以用来生成自定义的编程语言解析器。它的令人兴奋的点在于,它允许开发人员使用 JavaScript 语言来定义语法规则,然后将其转换为解析器,从而支持自定义的编程语言。
老码小张
2023/03/12
2.6K0
懂前端的你也可以轻松定义自己业务的DSL
P4:编写协议无关的包处理器
摘要 P4是一门编写协议无关的包处理器的高级语言。P4与SDN控制协议联合在一起工作,比如OpenFlow。在OpenFlow当前的协议形态中,它精确地指定了供它操作的协议头。这个协议头集合已经在短短的几年时间中,从12个域增长到了41个域,这同时也增加了协议的复杂性,但是仍然没有提供添加新的自定义首部的灵活性。 在这篇论文中我们将P4作为一个展示了OpenFlow在未来应该如何演进的草案协议而提出。我们有如下三个目标: 1.匹配域的重配置能力:在交换机被部署之后,开发者应该能够改变交换机处理数据包的方式
SDNLAB
2018/04/02
1.8K0
P4:编写协议无关的包处理器
从0开始自制解释器——添加对乘除法的支持
在上一篇中,我们实现了对减法的支持,并且介绍了语法图。针对简单的语法进行描述,用语法图描述当然是没问题的。但是针对一些复杂的语法进行描述,如果每个部分都通过语法图来描述就显得有些繁琐了。这篇我们先介绍另一种描述语法的方式,并进一步介绍一些关于语法分析的知识。
Masimaro
2023/03/24
5250
Chomsky文法类型判断
0型文法或短语结构文法的相应语言称为0型语言或短语结构语言L0。这种文法由于没有其他任何限制,因此0型文法也称为无限制文法,其相应的语言称为无限制性语言。任何0型语言都是递归可枚举的,故0型语言又称递归可枚举集。这种语言可由图灵机(Turning)来识别。
里克贝斯
2021/05/21
1.2K0
Chomsky文法类型判断
【计算理论】上下文无关语法 ( CFG ) 转为 下推自动机 ( PDA )
最终的 上下文无关语法 ( CFG ) 转为的 下推自动机 ( PDA ) 样式 :
韩曙亮
2023/03/27
7900
【计算理论】上下文无关语法 ( CFG ) 转为 下推自动机 ( PDA )
JAVA的平台无关性如何实现?
◆平台无关性                       ◆语言特性 ◆面向对象                           ◆类库 ◆GC                                    ◆异常处理
名字是乱打的
2022/05/13
4740
JAVA的平台无关性如何实现?
65.精读《手写 SQL 编译器 - 文法介绍》
我们将一块语法规则称为 产生式,使用 “Left → Right” 表示任意产生式,用 “Left => Right” 表示产生式的推导过程,比如对于产生式:
黄子毅
2022/03/14
5820
编译原理文法详解_编译原理为什么存在递归文法
学完了词法分析,我们知道词法分析器将正则表达式转换成词法单元流,但对于这个记号流我们不知道是否能由正确的文法产生,因此我们需要通过语法分析器来检测其合法性。语法分析器的输出是一棵语法分析树(无论显性还是隐性),并且进行一些语法纠错处理。语法分析的整个过程大概就是我们先定义一个语法,再用相应的算法来检测我们的词法单元流是否符合该语法。这里主要讨论上下文无关文法构成的语法和自顶向下、自底向上的语法分析。
全栈程序员站长
2022/11/17
8000
编译原理文法详解_编译原理为什么存在递归文法
用c语言手搓一个500+行的类c语言解释器: 给编程初学者的解释器教程(4)- 语法分析1
我们来看看两个概念,EBNF和递归下降文法,以及如何用这两个方法来计算tryC中的表达式。
云微
2020/06/05
1.8K0
用c语言手搓一个600行的类c语言解释器: 给编程初学者的解释器教程(4)- 语法分析1:EBNF和递归下降文法
用c语言手搓一个600行的类c语言解释器: 给编程初学者的解释器教程(1)- 目标和前言 用c语言手搓一个600行的类c语言解释器: 给编程初学者的解释器教程(2)- 简介和设计 用c语言手搓一个600行的类c语言解释器: 给编程初学者的解释器教程(3)- 词法分析 用c语言手搓一个600行的类c语言解释器: 给编程初学者的解释器教程(4)- 语法分析1:EBNF和递归下降文法 用c语言手搓一个600行的类c语言解释器: 给编程初学者的解释器教程(5)- 语法分析2: tryC的语法分析实现 用c语言手搓一个600行的类c语言解释器: 给编程初学者的解释器教程(6)- 语义分析:符号表和变量、函数
云微
2023/02/11
5640
【计算理论】上下文无关语法 ( 代数表达式 | 代数表达式示例 | 确定性有限自动机 DFA 转为 上下文无关语法 )
此时可以得到语法分析树 ; 该语法分析树是一个代数表达式 ; 将该语法分析树写出 , 即可理解 上下文无关 语法 ;
韩曙亮
2023/03/27
4780
【计算理论】上下文无关语法 ( 代数表达式 | 代数表达式示例 | 确定性有限自动机 DFA 转为 上下文无关语法 )
JavaScript 语言通识 — 重学 JavaScript
在这个重学系列的课程中,都会假设大家对 JavaScript、CSS、HTML 有了一定的了解。而这个重学的过程其实是帮助我们在这些过去的知识里面建立一个新的秩序,也就是建立知识体系的过程。在重学 JavaScript 的过程将会带着大家以 JavaScript 的语法为线索,从细到粗的跟大家完整学习一遍 JavaScript 的语言知识
三钻
2020/10/29
7000
JavaScript 语言通识 — 重学 JavaScript

相似问题

上下文无关文法

10

上下文无关文法

20

如何编写给定条件的上下文无关文法

10

上下文无关文法还是上下文敏感文法?

23

上下文无关文法转换

313
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档