【问题标题】:Javascript Passing Object into Object MethodJavascript将对象传递给对象方法
【发布时间】:2017-04-19 21:53:56
【问题描述】:

正如标题所示,我正在尝试将对象传递给 Javascript 中的对象方法。更准确地说,我正在尝试将矢量对象实现到我需要创建的简单物理引擎中,并且我想在我的矢量对象中添加一个函数,该函数将向其中添加另一个矢量。可悲的是,当我尝试这样做时,在方法中存储向量的参数一直说它是未定义的。你能告诉我为什么它是未定义的以及如何解决它吗?我到处搜索,找不到任何可以解决我的特定问题的东西。这是我的代码:

function launch() {

running = false;

var payloadMass = 5291.7; // For SES-10 (kg)
var fairingMass = 2000; // (kg)

var time = 0;
var seconds = 0;
var minutes = 0;
var hours = 0;

var massFirstF = 438200; // (kg)
var massFirstE = 27200; // (kg)
var thrustFirst = 7607; // (kN)
var thrustFirstVac = 8227; // (kN)
var timeFirst = 162; // (sec) [162]

var massSecondF = 116000; // (kg)
var massSecondE = 4500; // (kg)
var thrustSecond = 934; // (kN)
var timeSecond = 397; // (sec)

//var gravity = 9.81; // (m/s^2)
var gravity = new vector2(0, -9.81);

var fuelFirst = 411000; // (kg) [411000]
var fuelFirstF = 411000; // (kg) [411000]
var fuelSecond = 111500; // (kg)
var fuelSecondF = 111500; // (kg)
var fuelFlowFirst = fuelFirst / timeFirst; // (kg/s)
var fuelFlowSecond = fuelSecond / timeSecond; // (kg/s)

var fuel = fuelFirst; // (kg)
var full = fuelFirstF; // (kg)

var stage = 0; // 0=First 1=Second 2=Payload
//var altitude = 0; // (m)
var velocity = 0; // (m/s)
//var acceleration = 0; // (m/s^2)
var acceleration = new vector2(0, 0);
//var accelDiff = acceleration - gravity; // (m/s^2)
var accelDiff = new vector2(0, acceleration - gravity.y);
var mass = massFirstF + massSecondF + payloadMass + fairingMass; // (kg)

var tempTime = 0;

var canvas = document.getElementById('canvas');
canvas.width = canvas.scrollWidth;
canvas.height = canvas.scrollHeight;
var ctx = canvas.getContext('2d');

ctx.font = "15px Arial";

var start = new buttonC(canvas.width / 2, canvas.height / 2, 100, 100 , "blue");

canvas.addEventListener('click', function(evt) {
var mousePos = getMousePos(canvas, evt);

if (isInside(mousePos, start)) {
    running = !running;
}else{

}   
}, false);

start.draw(ctx);

var spacexImg = new Image();
spacexImg.src="http://www.spacex.com/sites/all/themes/spacex2012/images/falcon9/falcon9-render.png";
spacexImg.width = spacexImg.width / 20;
spacexImg.height = spacexImg.height / 20;
var plumeImg = new Image();
plumeImg.src="plume.jpg";

plumeImg.height = (plumeImg.width / spacexImg.width) * plumeImg.height;
plumeImg.width = spacexImg.width;

var falcon = new rocket(spacexImg, (canvas.width / 2) - (spacexImg.width / 2), (canvas.height ) - (spacexImg.height));

setInterval(function(){
    if (running){
        if (stage == 0){
            fuelFirst = fuelFirst - (fuelFlowFirst * 0.01);
            mass = (massFirstE + fuelFirst) + massSecondF + payloadMass + fairingMass;
            acceleration.y = ((thrustFirst * 1000) / (mass));
            fuel = fuelFirst;
            full = fuelFirstF;
        if (fuel <= 0){
            stage = 1;
            tempTime = time;
        }
    }
    if (stage == 1){
        if (time <= (tempTime + 5)){
            acceleration.x = 0;
            acceleration.y = 0;
        }
        else{
            fuelSecond = fuelSecond - (fuelFlowSecond * 0.01);
            mass = (massSecondE + fuelSecond) + payloadMass + fairingMass;
            acceleration.y = ((thrustSecond * 1000) / (mass));
            fuel = fuelSecond;
            full = fuelSecondF;
            if (fuel <= 0){
                stage = 2;
                tempTime = time;
                acceleration.x = 0;
                acceleration.y = 0;
                fuel = 0;
            }
        }
    }

    //accelDiff = acceleration - gravity;
    accelDiff.add(acceleration.sub(gravity, 1), 1);
    falcon.vel.add(accelDiff, 0.01);
    //velocity = velocity + (accelDiff * 0.01);
    falcon.loc.add(velocity, 0.01);

    time = time + 0.01;
    minutes = truncateDecimals((time / 60) - (hours * 60), 0);
    seconds = truncateDecimals(time - ((minutes * 60) + (hours * 3600)), 0);
    hours = truncateDecimals((time / 60) / 60, 0);


    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = "black";
    ctx.fillText("Time = " + truncateDecimals(time, 0)
           + " sec. Or: " + hours + 
             " hours, " + minutes + 
             " minutes, " + seconds + 
             " seconds.", 10, 30)
    ctx.fillText("Altitude: " + truncateDecimals(falcon.loc.y, 2) + " meters", 10, 45);
    ctx.fillText("Acceleration: " + truncateDecimals(accelDiff, 2) + " m/s^2", 10, 60)
    ctx.fillText("Velocity: " + truncateDecimals(velocity, 2) + " m/s", 10, 75);
    ctx.fillText("Mass: " + truncateDecimals(mass, 2) + " kg", 10, 90);
    ctx.fillStyle = "green";
    ctx.fillText("Fuel: ", 10, 105);
    ctx.fillRect(10, 120, 50, 104);
    ctx.strokeStyle = "red";
    ctx.beginPath();
    ctx.moveTo(10, 122 + (100 - ((fuel / full) * 100)));
    ctx.lineTo(70, 122 + (100 - ((fuel / full) * 100)));
    ctx.stroke();
    ctx.fillText(truncateDecimals((fuel / full) * 100, 1) + "%", 70, 122 + (100 - ((fuel / full) * 100)));
    ctx.fillStyle = "yellow";
    ctx.fillRect(15, 122 + (100 - ((fuel / full) * 100)), 40, ((fuel / full) * 100));
    //falcon.loc.y = (canvas.height - spacexImg.height) - falcon.loc.y;
    falcon.draw(ctx);
    if (acceleration > 0){
        ctx.drawImage(plumeImg, falcon.loc.x , falcon.loc.y + spacexImg.height, plumeImg.width, plumeImg.height);   
    }
}
}, 10);
};

//Function to check whether a point is inside a rectangle
function isInside(pos, buttonC){
    return pos.x > buttonC.x && pos.x < buttonC.x+buttonC.width && pos.y < buttonC.y+buttonC.height && pos.y > buttonC.y;
}

function buttonC(x, y, width, height, color){
    this.x = x - (width / 2);
    this.y = y - (height / 2);
    this.width = width;
    this.height = height;
    this.color = color;
    this.draw = function (ctx){
        ctx.fillStyle = color;
        ctx.fillRect(this.x, this.y, width, height);
    };
}

function getMousePos(canvas, event) {
    var rect = canvas.getBoundingClientRect();
    return {
    x: event.clientX - rect.left,
    y: event.clientY - rect.top
    };
}

truncateDecimals = function (number, digits) {
    var multiplier = Math.pow(10, digits),
    adjustedNum = number * multiplier,
    truncatedNum = Math[adjustedNum < 0 ? 'ceil' : 'floor'](adjustedNum);

    return truncatedNum / multiplier;
};

function vector2(x, y) {
    this.x = x;
    this.y = y;
    this.add = function (vect, multiplier){
        this.x = this.x + (vect.x * multiplier);
        this.y = this.y + (vect.y * multiplier);
    this.sub = function (vect, multiplier){
        this.x = this.x - (vect.x * multiplier);
        this.y = this.y - (vect.y * multiplier);
    };
}

function rocket(img, x, y) {
    this.img = img;
    this.loc = new vector2(x, y);
    this.vel = new vector2(0, 0);
    this.draw = function(ctx) {
        ctx.drawImage(img, this.loc.x, this.loc.y, img.width, img.height);
    }
};

【问题讨论】:

  • 你怎么称呼那个函数和方法?
  • this 取决于执行上下文,而不是它的定义方式。
  • 这只是唯一相关的部分,我可以把它全部给你,但它的行为就像你把它自己放到一个文件中一样。
  • 不,如果我运行此代码,则不会发生任何事情。我们需要产生错误的代码。不是整个脚本,只是一个示例调用来说明您遇到的错误。
  • 好的,我现在就去。

标签: javascript html object methods undefined


【解决方案1】:

您需要确保在调用vector2 时使用new 关键字(var vector = new vector2()),否则您对this 的引用将指向您的函数以外的其他内容(如果您是,则可能是window在浏览器中运行):

function vector2(x, y) {
   this.x = x;
   this.y = y;
   this.add = function (vect, multiplier){
      this.x = this.x + (vect.x * multiplier);
      this.y = this.y + (vect.y * multiplier);
   };
}

var vec1 = new vector2(10, 10);
var vec2 = new vector2(20, 20);
vec1.add(vec2, 5);

console.log(vec1.x, vec1.y);

使用完整源代码查看您的编辑后,您的代码预计 .add.sub 返回实例

// .add expects a vector, .sub does not return a vector
accelDiff.add(acceleration.sub(gravity, 1), 1);

并且这些方法没有返回语句(因此它们返回undefined)。试试这个:

this.add = function (vect, multiplier){
    this.x = this.x + (vect.x * multiplier);
    this.y = this.y + (vect.y * multiplier);
    return this;
};
this.sub = function (vect, multiplier){
    this.x = this.x - (vect.x * multiplier);
    this.y = this.y - (vect.y * multiplier);
    return this;
};

【讨论】:

  • 我一直在使用 new 关键字,正如您现在所看到的。
  • 现在可以使用了!!非常感谢,我只是想知道,我的代码在哪里期望呢?这将非常有帮助,然后我可以将您的答案标记为正确答案。
  • 找到了 - accelDiff.add(acceleration.sub(gravity, 1), 1); - .sub 的返回值必须是 .add 工作的向量。
  • @James 是的,就是这个!我用有问题的行更新了我的答案
  • @user140052 很高兴,很高兴它现在为您工作! :-)
【解决方案2】:

这行有问题:

accelDiff.add(acceleration.sub(gravity, 1), 1);

sub 的调用没有返回值,因此您将undefined 作为第一个参数传递给add

所以你真的应该分开调用,像这样:

acceleration.sub(gravity, 1);
accelDiff.add(gravity, 1);

解决这个问题的一个好方法是让你的向量方法返回this

function vector2(x, y) {
    this.x = x;
    this.y = y;
    this.add = function (vect, multiplier){
        this.x = this.x + (vect.x * multiplier);
        this.y = this.y + (vect.y * multiplier);
        return this; // <----
    this.sub = function (vect, multiplier){
        this.x = this.x - (vect.x * multiplier);
        this.y = this.y - (vect.y * multiplier);
        return this; // <----
    };
}

有了这个改变,你可以写:

accelDiff.add(acceleration.sub(gravity, 1), 1);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-09
    • 2011-09-27
    • 2014-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-05
    • 2019-03-22
    相关资源
    最近更新 更多