1

How come when I use the following code, clicking on "Click Here" doesn't trigger an alert? Why can't I call methods of things other than the window object? E.g. a method of the test1 function?

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">

function test1() {
    test1.test2 = function() {
        alert('Test');
    }
}

</script>
</head>
<body>
<div onClick="test1.test2()">Click Here</div>
</body>
</html>
2
  • 1
    @Chimoo - That's incorrect. Functions are objects, too. Commented Feb 27, 2011 at 21:37
  • thanks for that, didn't realise Commented Feb 27, 2011 at 22:20

4 Answers 4

3

Since you're defining test1.test2 inside of test1, it won't actually be defined until test1 executes.

Adding a call to test1() immediately after its definition in the script block would make your code work.

You could also move the definition of test1.test2 outside of test1, though if anything in test2 relies on variables which are scoped to test1 you'd have an issue.

All that said, you're describing a weird scenario, code-wise.

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

2 Comments

Thanks for your answer. I know it's a strange/artificial set up, but I'm trying to understand how javascript works as opposed to write realistic code.
No problem. I realized it was a simplified scenario which is why my answer didn't get into object instantiation, etc. Given your real code we could go further to suggest a best practice. But as is, I can only explain why the code fails when run as you posted it.
3

test1.test2 is undefined until test1() has been called.

~$ rhino
Rhino 1.7 release 2 2009 03 22
js> function test1() { 
  > test1.test2 = function() { print( 'Test\n' ); } 
  > }
js> test1

function test1() {
    test1.test2 = function () {
        print("Test\n");
    };
}

js> test1.test2   # Undefined!
js> test1()
js> test1.test2

function () {
    print("Test\n");
}

js> test1.test2()
Test

Comments

0

test1 is a function, not an object.

For example, the following would work:

<script type="text/javascript">
test1 = {
    test2 : function(){
        alert('Test');
    }
}
</script>
<div onClick="test1.test2()">Click Here</div>

Or

<script type="text/javascript">
function test1() {
    this.test2 = function(){
        alert('Test');
    }
}
var t1 = new test1();
</script>
<div onClick="t1.test2()">Click Here</div>

5 Comments

You're only partially correct. Everything in JS is an object, including functions. So functions can have methods statically assigned as in the example. I don't know if I'd do it, and maybe you're right w/ regard to the OP's intent, but I wanted to point it out.
Doesn't really have to use "new" like that; the function could just be called any old way. Once it runs once, it'll have the effect of adding the property "test2" to the function.
Thanks for your answer. I have a closely related question. In my original code, test1 is a method of the window object, but what about test2? Is it a method of any object?
true, JS has an annoying way of mangling common terminilogy :D. I guess, more accurately, the function isn't being called, so you need to construct something else before you use it, or you need to call a function that returns something useful. But just describing it as above seemed easier.
ah I see... so the right way to think about it is this: before test1 is called, test2 doesn't exist, but as soon as test1 is called, test2 comes into existence as a method of test1
0
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">

function test1(){

test1.prototype.test2 = function(){
alert('Test');
}

}


</script>
</head>
<body>

<div onClick=" var u = new test1();u.test2()">Click Here</div>
</body>
</html>

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.