'this'在原型方法中未定义,该方法使用Promise并从同一对象的其他原型方法调用?

时间:2017-10-29 13:54:07

标签: javascript promise prototype-programming

我正在创建一个简单的表单,我们有2个日期输入并检查日期对象的有效性;我正在遵循原型模式并创建2方法。

到目前为止这工作正常但是当我在验证方法中使用Promise时,它会给出错误“无法读取未定义的属性'startDate'”。所以我的问题是为什么在这种情况下这是不确定的?

以及如何解决?

下面是我的代码段。

(function() {
    'use strict';


    let startDate, endDate;

    const _calculate = function() {
        // console.log('inside constructor');
        this.endDate = new Date();
        this.ageFind = true; // for first tab
    };

    _calculate.prototype = {
        //function to get data for calculating the time diff (setting startDate, endDate )
        init: function(formName) {
            // console.log("getDifference");
            if (this.countdown) {
                clearInterval(this.countdown);
            }
            // other form name is 'secondForm'
            this.ageFind = (formName === 'firstForm') ? true : false;
            var fd = new FormData(document.getElementById(formName));
            // Start date
            let startDay = fd.get('start_date');
            let startMonth = fd.get('start_month');
            let startYear = fd.get('start_year');
            this.startDate = new Date(`${startMonth}-${startDay}-${startYear}`);
            // End date
            let endDay = fd.get('end_date');
            let endMonth = fd.get('end_month');
            let endYear = fd.get('end_year');
                this.endDate = new Date(`${endMonth}-${endDay}-${endYear}`);
           
            this.isValidDate().then((res) => {
                console.log('is valid');
            }).catch((err) => {
                console.error('Invalid date.', err);
            });
        },

        isValidDate: function() {
            console.log("validateDate", this.startDate, this.endDate);
            return new Promise( function(resolve, reject) {
                console.log('inside promise');
                if (isFinite(this.startDate) && isFinite(this.endDate)) {
                    var [startTimeStamp, endTimeStamp] = [this.startDate.getTime(), this.endDate.getTime()];
                    // console.log("startTimeStamp, endTimeStamp", startTimeStamp, endTimeStamp);
                    // swap the date if `end date` is smaller than `start date`
                    if (endTimeStamp < startTimeStamp) {
                        [this.startDate, this.endDate] = [this.endDate, this.startDate];
                    }
                    resolve(true);
                } else {
                    reject(false);
                }
            });
        }
    };

    window._cal = new _calculate();
})();
div {
float: left;
}

.start-date,.end-date {
 margin: 4px;
 }
<form name="firstForm" id="firstForm">
    <fieldset class="start-date">
    <legend>Start Date</legend>
    <select id="start_date" name="start_date">
        <option selected disabled>Start Date</option>
        <option value="1">1</option>
    </select>
    <select id="start_month" name="start_month">
        <option selected disabled>Start Month</option>
        <option value="10">October</option>
    </select>
    <select id="start_year" name="start_year">
        <option selected disabled>Start Year</option>
        <option value="2016">2016</option>
        <option value="2017">2017</option>
    </select>
    </fieldset>
    <fieldset class="end-date">
    <legend> End date</legend>
        <select id="end_date" name="end_date">
        <option selected disabled>End Date</option>
        <option value="1">1</option>
    </select>
    <select id="end_month" name="end_month">
        <option selected disabled>End Month</option>
        <option value="10">October</option>
    </select>
    <select id="end_year" name="end_year">
        <option selected disabled>End Year</option>
        <option value="2016">2016</option>
        <option value="2017">2017</option>
    </select>
    </fieldset>
    <br/>
    <button type="button" onclick="_cal.init('firstForm')">Calculate!</button>
</form>

1 个答案:

答案 0 :(得分:2)

由于function导致上下文丢失,您需要关闭它:

    isValidDate: function() {
         var self = this;
        return new Promise( function(resolve, reject) {
            console.log(self.startDate);
            // ...
        });
    }