Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not a function?

When I run the following code I get told, that talk is not a function. Why?

function cat(name) {
    talk = function() {
        alert(" say meeow!" )
    }
} 

cat("felix");
cat.talk()
like image 419
dublintech Avatar asked Mar 16 '12 22:03

dublintech


People also ask

Is not a function means?

The JavaScript exception "is not a function" occurs when there was an attempt to call a value from a function, but the value is not actually a function.

Which one is not a function?

Option B is correct.. y2 = x is not a function as for each value of x, we will get 2 values of y.. which is not as per the definition of a function..

Why is it called not a function?

A TypeError: "x" is not a function occurs when a function is called on an object that does not contain the called function. When calling a built-in function that expects a callback function argument, which does not exist. When the called function is within a scope that is not accessible.


2 Answers

What you're trying to do is create an object for which the function is a constructor, but what the code is actually doing is setting the variable talk to a function. You want:

function cat(name) {
    this.talk = function() {
        alert(" say meeow!" )
    }
} 

var myCat = new cat("felix");
myCat.talk()

edit:

Relevant javascript tech talk: http://www.youtube.com/watch?v=ljNi8nS5TtQ

He talks about constructing objects with functions at about 30 minutes in. The code he posts is:

function Circle(radius){
    this.radius = radius;
    this.area = function(){
        return this.radius * this.radius * Math.PI;
    };
}
var instance = {};
Circle.call(instance, 5);
instance.area(); // ==> 78.5398
var instance2 = new Circle(5);
instance2.area() // ==> 78.5398
instance instanceof Circle // ==> false
instance2 instanceof Circle // ==> true

And the relevant quote:

The new keyword is just a shorthand that is saying "make a new object and call the constructor on it ... the new keyword has no other meaning"

In other words, he's saying that when using the new keyword, you're defining your variable as an object and calling the function in the context of that object (this points to your object).

The extra thing that the new keyword does is set the prototype of the newly made object to the prototype of the constructor. So if we do:

function Circle(radius){
    this.radius = radius;
    this.area = function(){
        return this.radius * this.radius * Math.PI;
    };
}
var instance = {};
Circle.call(instance, 5);
instance.__proto__ = Circle.prototype; // we set the prototype of the new object to that of the constructor
instance.area(); // ==> 78.5398
var instance2 = new Circle(5);
instance2.area() // ==> 78.5398
instance instanceof Circle // ==> true // this is now true 
instance2 instanceof Circle // ==> true

instance instanceof Circle is now true.

like image 131
mowwwalker Avatar answered Oct 04 '22 09:10

mowwwalker


To make your code work as desired you would have to write:

function Cat(name) {
    this.talk = function() {
        alert(" say meeow!" )
    }
};

var c = new Cat("felix");
c.talk()

The function Cat is then a constructor function, and the returned object has a property (talk) which is a function that you can call.

Your original code actually declared a global function talk which wasn't part of the cat function at all, since it was missing the var keyword.

like image 34
Alnitak Avatar answered Oct 04 '22 09:10

Alnitak