1

The following script:

    <script>
        function Parenizor (value){
            this.setValue(value);
        }

        Parenizor.method('setValue', function (value){
            this.value = value;
            return this;
        });

        Parenizor.method('getValue', function (){
            return this.value;
        });

        Parenizor.method('toString', function(){
            return '(' + this.getValue() + ')';
        });

        myParenizor = new Parenizor(0);
        myString = myParenizor.toString();

        console.log(myParenizor, myString);
    </script>

in the console I can see: "undefined is not a function" referring to:

Parenizor.method('setValue', function (value){

Am I missing something?

Aessandro
  • 5,517
  • 21
  • 66
  • 139
  • 1
    That is Douglass Crockford code. He has some good code but to this day is unable to produce a correct example of what he calls "classical inheritance". The method is something Crockford added to the Function.prototype (bad because it breaks encapsulation) and calls "sugar". You may be better off reading this answer about "classical inherritance" http://stackoverflow.com/a/16063711/1641941 or this book: https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&%20object%20prototypes/README.md#you-dont-know-js-this--object-prototypes – HMR Apr 08 '15 at 23:55

2 Answers2

5

Functions don't have a method property, which is why you're getting undefined. You may be thinking of an extension to functions that Douglas Crockford likes to use, which looks like this:

Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this;
};

But that's not part of JavaScript, it's a Crockford thing. You'd have to have that code in your code and execute it before you do your thing in order to use it.

As you can see, it does virtually nothing; it's the smallest bit of syntactic sugar. To create your setValue method without it, for instance, you'd do this:

Parenizor.prototype.setValue = function(value) {
  this.value = value;
  return this;
};

If you don't want to use Crockford's method function, just do that instead.


Side note: You're falling prey to The Horror of Implicit Globals; you need to declare your myParenizor and myString variables.


Live example of defining Crockford's method before using it (and declaring the variables):

Function.prototype.method = function(name, func) {
  this.prototype[name] = func;
  return this;
};

function Parenizor(value) {
  this.setValue(value);
}

Parenizor.method('setValue', function(value) {
  this.value = value;
  return this;
});

Parenizor.method('getValue', function() {
  return this.value;
});

Parenizor.method('toString', function() {
  return '(' + this.getValue() + ')';
});

var myParenizor = new Parenizor(0);
var myString = myParenizor.toString();

snippet.log(JSON.stringify(myParenizor));
snippet.log(myString);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
2

You want to add your methods onto the protoype of your object.

From MDN:

All objects in JavaScript are descended from Object; all objects inherit methods and properties from Object.prototype. So when you run new Parenizor(0) you will create a new instance of Parenizor which will have all the functions available that where defined on its prototype.

So you need to extend the prototype of your function:

Parenizor.prototype.setValue = function (value){
    this.value = value;
    return this;
};
Joey Ciechanowicz
  • 3,345
  • 3
  • 24
  • 48