1

I'm trying to translate a PHP class into JavaScript. The only thing I'm having trouble with is getting an item out of an array variable. I've created a simple jsfiddle here. I cannot figure out why it won't work.

(EDIT: I updated this code to better reflect what I'm doing. Sorry for the previous mistake.)

function tattooEightBall() {

this.subjects = ['a bear', 'a tiger', 'a sailor'];

this.prediction = make_prediction();

var that = this;



function array_random_pick(somearray) {
      //return array[array_rand(array)];
      var length = somearray.length;

      var random = somearray[Math.floor(Math.random()*somearray.length)];
    return random;


}


function make_prediction() {

    var prediction = array_random_pick(this.subjects);
    return prediction;
}

}
var test = tattooEightBall();
document.write(test.prediction);

7 Answers 7

4

Works fine here, you are simple not calling

classname();

After you define the function.

Update

When you make a call to *make_prediction* , this will not be in scope. You are right on the money creating a that variable, use it on *make_prediction* :

var that = this;

this.prediction = make_prediction();

function make_prediction() {
  var prediction = ''; //initialize it

  prediction = prediction + array_random_pick(that.subjects);
  return prediction;
}

You can see a working version here: http://jsfiddle.net/zKcpC/

This is actually pretty complex and I believe someone with more experience in Javascript may be able to clarify the situation.

Edit2: Douglas Crockfords explains it with these words:

By convention, we make a private that variable. This is used to make the object available to the private methods. This is a workaround for an error in the ECMAScript Language Specification which causes this to be set incorrectly for inner functions.

To see the complete article head to: http://javascript.crockford.com/private.html

Sign up to request clarification or add additional context in comments.

6 Comments

Ha! Sorry I stripped down the code too much and I guess it removed my problem. I've revised the code with a more accurate version of my code (which doesn't work): jsfiddle.net/YznSE/7
Emerson, so it still doesn't work? If you could provide the page you are working on, or the exact function/usage on fiddle you have, we may be able to help.
You didn't return anything from tattooEightBall. Try adding a return this; at the end of the function.
AHA. That made it work on jsfiddle, but for some reason I can't get my actual code to work. Here's a newer jsfiddle (I can't figure out why THIS won't work exactly the same way!). I get an error saying that the "length" property of my "subjects" array is undefined: jsfiddle.net/wpZ5A
@Emerson - take a look at my answer for a working jsFiddle that makes a class. It looks to me like you don't understand how the this operator works in javascript. If you just call a plain javascript function, then this is set back to window in that function. You either have to use fn.apply(this, ...) or obj.fn(...) to cause the value of this to be set properly. In your fiddle, when you call make_prediction(), it looses the value of this so then that value isn't set properly inside of the function and you get a javascript error.
|
0

You never call classname. Seems to be working fine.

Comments

0

Works for me:

(function classname() {

this.list = [];
this.list[0] = "tiger";
this.list[1] = "lion";
this.list[2] = "bear";

function pickone(somearray) {
    var length = somearray.length;          
    var random  = somearray[Math.floor(Math.random()*length)];
    return random;
}


var random_item = pickone(this.list);

document.write(random_item);

}());

Were you actually calling the classname function? Note I wrapped your code block in:

([your_code]());

Comments

0

I'm not sure what you're trying to accomplish exactly with the class structure you were using so I made some guesses, but this code works by creating a classname object that has instance data and a pickone method:

function classname() {

    this.list = [];
    this.list[0] = "tiger";
    this.list[1] = "lion";
    this.list[2] = "bear";

    this.pickone = function() {
        var length = this.list.length;          
        var random  = this.list[Math.floor(Math.random()*length)];
        return random;
    }
}

var cls = new classname();
var random = cls.pickone();

You can play with it interactively here: http://jsfiddle.net/jfriend00/ReL2h/.

Comments

0

It's working fine for me: http://jsfiddle.net/YznSE/6/ You just didn't call classname(). If you don't call it, nothing will happen ;)

Comments

0

Make it into a self-executing function like this:

(function classname() {

this.list = [];
this.list[0] = "tiger";
this.list[1] = "lion";
this.list[2] = "bear";

function pickone(somearray) {
    var length = somearray.length; //<---WHY ISN'T THIS DEFINED??       
    var random = somearray[Math.floor(Math.random() * length)];
    return random;
}


var random_item = pickone(this.list);

document.write(random_item);
})();

Comments

0
var test = tattooEightBall();
document.write(test.prediction);

Should be:

var test = new tattooEightBall(); //forgot new keyword to create object
document.write(test.prediction()); // forgot parens to fire method

and:

this.prediction = make_prediction();

Should be:

this.prediction = make_prediction;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.