简体   繁体   中英

Why is my function being returned correctly when prototyped outside of my constructor, but not when it's being used as a method within my constructor?

I have a function constructor which needs to have a method being used as one of the properties within the constructor. Normally, I'd simply create the function as a property like so:

var currentDate = new formatDate(new Date());
console.log(currentDate.year, currentDate.month, currentDate.dayOfMonth, currentDate.dayOfWeek, currentDate.second);


function formatDate(dateHolder){
    this.monthsArray = ["Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec"];
    this.daysOfWeekArray = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
    this.date = new Date(dateHolder);
    this.year = this.date.getFullYear();
    this.month = this.monthsArray[this.date.getMonth()];
    this.dayOfMonth = this.addZero(this.date.getDate());
    this.dayOfWeek = this.daysOfWeekArray[this.date.getDay()];
    this.minute = this.addZero(this.date.getMinutes());
    this.second = this.addZero(this.date.getSeconds());
    this.addZero = function(i){
        if(i < 10){
            i = "0" +i;
        }
        return i;
    }
}

I've always been taught that this would work and is the way to do this. However, whenever I run my application, I get the the error saying that this.addZero is not a function. When I do the same thing, but prototype the addZero method like so

formatDate.prototype.addZero = function(i){
    if(i < 10){
        i = "0" +i;
    }
    return i;
}

function formatDate(dateHolder){
    this.monthsArray = ["Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec"];
    this.daysOfWeekArray = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
    this.date = new Date(dateHolder);
    this.year = this.date.getFullYear();
    this.month = this.monthsArray[this.date.getMonth()];
    this.dayOfMonth = this.addZero(this.date.getDate());
    this.dayOfWeek = this.daysOfWeekArray[this.date.getDay()];
    this.minute = this.addZero(this.date.getMinutes());
    this.second = this.addZero(this.date.getSeconds());
}

it works the way it's supposed to.

Can anyone explain to me why it's working one way but not the other, if I'm doing something wrong(and how to fix it), and which way is the right way?

You're calling addZero before you've defined it. Switch it around so that you define it first and it will work:

this.addZero = function(i){
    if(i < 10){
        i = "0" +i;
    }
    return i;
};
this.dayOfMonth = this.addZero(this.date.getDate());
this.dayOfWeek = this.daysOfWeekArray[this.date.getDay()];
this.minute = this.addZero(this.date.getMinutes());
this.second = this.addZero(this.date.getSeconds());

or, since the function doesn't use this you can just use a function declaration and rely on hoisting:

this.dayOfMonth = addZero(this.date.getDate());
this.dayOfWeek = this.daysOfWeekArray[this.date.getDay()];
this.minute = addZero(this.date.getMinutes());
this.second = addZero(this.date.getSeconds());

function addZero(i){
    if(i < 10){
        i = "0" +i;
    }
    return i;
};

Arguably you should always use the prototype whenever you can anyway (when the body of the function doesn't need access to any variables that are declared in the constructor). Functions added to the prototype are reused by every object, but functions created in the constructor are duplicated (a new function is created for each object, which is not necessary when you don't use any variables that closed over).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM