首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么我不使用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

复制
相关文章
Droid@screen:在PC屏幕上显示Android手机屏幕
这里介绍一款工具——Droid@screen,用来获取手机屏幕,显示在PC屏幕上。它集截图、录像等多种功能于一体。
流柯
2018/08/30
2.3K0
Android 手机如何拍摄RAW图
专业玩摄影的朋友可能更倾向于使用相机的RAW格式,然后自己做后期处理,而不是直接拍摄JPEG格式的图片。
雪月清
2020/09/01
3.6K0
Android 手机如何拍摄RAW图
Android极速开发之手机屏幕
获取屏幕宽高 手机横竖屏的判断 public class ScreenUtils { public static int getWidth(Context context) { WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics();
Javen
2018/08/21
6040
Android动态控制手机屏幕方向
想要在应用中控制手机屏幕显示方向,可以在onCreate中用一句代码搞定: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); 手机屏幕的朝向有7个可选值,分别如下 SCREEN_ORIENTATION_BEHIND //继承Activity堆栈中当前Activity下面的那个Activity的方向 SCREEN_ORIENTATION_LANDSCAPE // 横屏(风景照) ,显示时宽度大于高度 SCREEN_O
张拭心 shixinzhang
2022/11/30
1.3K0
Android手机 全面屏(18:9屏幕)适配指南
从小米MIX 1发布以来,越来越多所谓“全面屏”手机发布,如三星S8,小米MIX2,VIVO X20,Google Pixel2等等...2017年下半年开始,“全面屏”将大范围覆盖,低至千元机水平,就像当年手机屏幕从720P到1080P过渡一样,历史车轮,滚滚向前,不可阻挡!
用户2802329
2018/08/07
1.9K0
Android手机 全面屏(18:9屏幕)适配指南
Android手机 全面屏(18:9屏幕)适配指南
从小米MIX 1发布以来,越来越多所谓“全面屏”手机发布,如三星S8,小米MIX2,VIVO X20,Google Pixel2等等…2017年下半年开始,“全面屏”将大范围覆盖,低至千元机水平,就像当年手机屏幕从720P到1080P过渡一样,历史车轮,滚滚向前,不可阻挡!
程思扬
2022/01/10
1.6K0
Android手机 全面屏(18:9屏幕)适配指南
手机拍摄动态照片如何制作成GIF表情或视频?以小米手机&iPhone为例转换
目前市面上的手机基本都支持动态照片的功能,iPhone上叫实况照片,Android以小米为例叫动态照片,其原理大概是拍摄一组照片合并展示,长按照片就可以播放动态过程,并且是有声音的。那么问题来了,拍摄下的动态照片如何制作成GIF表情或视频呢?本文主要解决这个需求。这里不使用任何第三方软件即可实现转换。
用户7715973
2021/02/02
32.9K0
浅谈屏幕拍摄泄密跟踪的检测技术
前言关注屏幕拍照安全检测技术介绍数字盲水印屏幕矢量水印摄像头检测屏摄检测缓解办法参考资料
安全乐观主义
2020/05/08
11K0
Anbox:在 Linux 上运行 Android 应用程序的简单方式
Anbox 是 “Android in a box” 的缩写。Anbox 是一个基于容器的方法,可以在普通的 GNU/Linux 系统上启动完整的 Android 系统。
用户8639654
2021/09/23
5.4K0
【Android 屏幕适配】屏幕适配基础概念 ④ ( 屏幕适配限定符 | 手机/平板电脑设备屏幕适配 )
Android 系统加载应用资源时 , 会根据当前运行应用的设备的相关属性 , 如 : 屏幕尺寸 / 屏幕像素密度 / 宽高比 / 屏幕方向 等属性 , 加载不同的屏幕适配限定符目录下的资源 ;
韩曙亮
2023/03/30
7.2K0
【Android 屏幕适配】屏幕适配基础概念 ④ ( 屏幕适配限定符 | 手机/平板电脑设备屏幕适配 )
现在,以编程方式在 Electron 中上传文件,是非常简单的!
本文主要探讨了在 Electron 应用中如何实现上传文件到服务器的功能,同时通过本地代理服务器来获取完整的cookie。首先介绍了在 Electron 应用中如何通过 XHR 上传文件到服务器,然后介绍了如何通过 LocalStorage 将文件保存在本地。最后,本文介绍了一种使用 Electron 创建本地代理服务器,从而获取完整的cookie的方法。
ios122
2017/12/27
5.3K0
现在,以编程方式在 Electron 中上传文件,是非常简单的!
在Windows上以服务方式运行 MSOPenTech/Redis
ServiceStack.Redis 使用教程里提到Redis最好还是部署到Linux下去,Windows只是用来做开发环境,现在这个命题发生改变了,在Windows上也可以部署生产环境的Redis,这都要感谢微软的开放,把Redis在Windows上的环境给我们搞定了,最新的版本已经支持64位了。那么Redis在32位上的存储能力受限于可用的地址空间,也就是3GB。 要在Windows上运行64位Redis ,可以从https://github.com/MSOpenTech/redis 获取一份Redis
张善友
2018/01/29
1.4K0
在Windows上以服务方式运行 MSOPenTech/Redis
【Android从零单排系列一】《Android系统发展史》
9.Android 4.0:​Ice Cream Sandwich(冰激凌三明治)
再见孙悟空_
2023/02/10
1.4K0
【Android从零单排系列一】《Android系统发展史》
点击加载更多

相似问题

Android以编程方式拍摄屏幕快照

51

在android中以编程方式拍摄屏幕截图

40

以编程方式拍摄屏幕快照

11

以编程方式拍摄位图屏幕截图

12

更改方向后以编程方式拍摄屏幕

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

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

洞察 腾讯核心技术

剖析业界实践案例

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