【问题标题】:Javascript and prototype inheritance issueJavascript和原型继承问题
【发布时间】:2013-11-03 00:33:38
【问题描述】:

有什么方法可以阻止函数的实例相互继承属性?我正在阅读一篇关于 Javascripts 原型对象的文章并阅读了以下内容。

“需要注意的是原型是“活的”。在JavaScript中对象是通过引用传递的,因此原型不会随着每个新的对象实例复制。这在实践中是什么意思?这意味着你可以修改任何时候的原型和所有对象(即使是在修改之前创建的对象)都将继承更改。”

有没有办法阻止所有对象更新。我想保持每个实例的属性都是唯一的。如果没有,还有其他方法可以将属性分配给函数吗?这是我正在使用的一些代码。它允许我在 three.js 中显示动画精灵,但是当我创建函数的新实例时,实例会跳转到新实例调用的帧。所以那里都显示相同的框架。我想如果我可以关闭继承它应该没问题。抱歉,如果我删除了一堆问题不需要的东西,那么我很草率。

   function slowToStopFunc(texture, tilesHoriz, tilesVert, numTiles, tileDispDuration) {
       this.tilesHorizontal = tilesHoriz;
       this.tilesVertical = tilesVert;
       this.numberOfTiles = numTiles;
       texture.wrapS = texture.wrapT = THREE.RepeatWrapping; 
       texture.repeat.set( 1 / this.tilesHorizontal, 1 / this.tilesVertical );
       this.tileDisplayDuration = tileDispDuration;
       this.currentDisplayTime = 0;
       this.currentTile = 3;            
           this.update3 = function( milliSec3 ) {
            this.currentDisplayTime += milliSec3;
            while (this.currentDisplayTime > this.tileDisplayDuration && adjustSpeed <= 2)
            {
        if (this.currentTile >= -1 && this.currentTile <= 14) { 
           this.currentTile++;
           }
        }   
        var currentColumn = this.currentTile % this.tilesHorizontal;
        texture.offset.x = currentColumn / this.tilesHorizontal;
        var currentRow = Math.floor( this.currentTile /      this.tilesHorizontal );  
        texture.offset.y = currentRow / this.tilesVertical;
        }    
        }

【问题讨论】:

  • 可以深度复制一个对象,因此它将是独立的....这是你想要的吗?您尝试实现的样本会有所帮助
  • @charlietfl 是的,对不起,我应该一开始就把它放在那里。你说的很对。
  • 所以您是说当您尝试new slowToStopFunc 时它会与其他实例发生反应?那是因为slowToStopFunc 是更大对象的一部分吗?
  • 我不太确定它为什么会做出反应。在阅读了原型继承之后,我发现新实例正在更新旧实例。这就是它的样子。 slowToStopFunc 不是另一个对象的一部分。但我在另一个函数中调用了新的 slowToStopFunc。

标签: javascript inheritance


【解决方案1】:

由于属性查找的工作方式,原型继承的性质允许您这样做。

发生属性查找时:

  1. 对象是否有someProperty?如果是,则返回 someProperty
  2. 如果对象没有someProperty,检查它的原型链并执行相同的逻辑,直到它的原型链接是null

基本上这意味着在对象上设置属性会自然地隐藏它的继承值。

function A() {
}

A.prototype.test = 'test';

var a = new A();

a.test = 'test 2';

console.log(a.test); //not test anymore

但是,如果您询问是否可以在不影响现有实例的情况下修改构造函数的原型,这是可能的,但我不知道您为什么要这样做。

基本上你只需要替换整个原型实例,这样新创建的实例就有一个全新的原型对象。

function A() {}

A.prototype.test = 'test';

var a = new A();

A.prototype = {
    constructor: A,
    test: 'new value'
};

console.log(a.test); //test

console.log(new A().test); //new value

【讨论】:

  • 感谢示例代码。在使用它定义属性时,我有办法替换整个原型实例。并在使用类似 var Playanimation = new slowToStopFunc(texture, tilesHoriz, tilesVert, numTiles, tileDispDuration) {
  • @JohnBob 您能否进一步扩展“跳转到新实例调用的框架”,并展示您如何实例化您的东西以及每个实例的哪些属性应该是唯一的。谢谢!
  • 我正在尝试使用上面的代码在three.js中播放动画。除非我添加一个以上的动画,否则它工作正常。似乎每个动画实例都在相互更新。在我的代码中,我有一行 this.update3 = function(milliSec3) {。然后我打电话给slowToStopFunc.update(1000*delta);我认为每次更新每个实例时都会更新所有实例。
  • 当然。我有一个轮子旋转的 16 个图像精灵表。在上面的代码中 this.currentTile 是递增的。这就是告诉动画要显示精灵表中的什么图像的原因。因此,当一个实例出现在屏幕上时,图像以正确的顺序显示,但是当我添加多个图像时,事情就开始出错了。假设车轮 1 在图像 5 上,并且需要一个新的车轮实例。现在轮子 2 尝试调用图像 1,轮子 1 和轮子都显示图像 1,但是轮子 1 尝试调用图像 6,两个轮子都显示图像 6,并且 2 个轮子争夺控制权。
  • @JohnBob 通过查看您的代码,我感觉所有实例都将共享相同的texture 对象。我从未使用过这个库,但也许这是你的问题。还要确保使用new 关键字创建实例...var instance = new slowToStopFunc(...); 然后更新...instance.update(...);slowTopStopFunc 函数的名称如果它是一个构造函数,也很容易引起误解。
【解决方案2】:

您是否尝试过覆盖继承的属性?不确定您对对象继承有多熟悉,但通常您可以通过匹配属性名称来覆盖继承的属性。

【讨论】:

  • 嗯,很有趣。我将如何覆盖属性?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
相关资源
最近更新 更多