我有以下JavaScript,如下所示
function getExpiryDate(contract) {
var expiryDay;
var contractType;
var today = new moment();
var today1 = new moment();
var x = myFunction(4, 3);
var abc =3;
var xyz= 4;
var c = myFunction(abc, xyz);
console.log("abc is: "+abc);
console.log("xyz is: "+xyz);
console.log(today1);
expiryDay = getlastDayofMonth('Thursday',today1);
console.log(today1); /* Why has the value of today changed? */
}
function getlastDayofMonth(dayName,date1) {
var endDate = date1.endOf('month');
var lastDayOfMonth = endDate.format('dddd');
var weekDayToFind = moment().day(dayName).weekday(); //change to searched day name
var searchDate = endDate; //now or change to any date
while (searchDate.weekday() !== weekDayToFind)
{
searchDate.subtract(1, 'days');
}
return searchDate;
}
function myFunction(a, b) {
return a * b; // Function returns the product of a and b
}
当我执行时,我得到以下输出。
expirydate.js:11 abc is: 3
expirydate.js:12 xyz is: 4
expirydate.js:13 Moment { _d: Wed Aug 31 2016 10:21:04 GMT+0530 }
expirydate.js:15 Moment { _d: Thu Aug 25 2016 23:59:59 GMT+0530 }
我完全混淆了为什么今天的值1在函数中使用时会发生变化。
答案 0 :(得分:4)
因为在JS中,对象是通过引用而不是通过值传递的。这意味着你正在处理同一个对象。
为了防止这种情况,你必须将函数中的date1值克隆到一个变量,该变量的范围仅限于函数
答案 1 :(得分:2)
这种情况正在发生,因为Moment是以可变的代码风格编写的。这是相当令人惊讶的行为。在阅读了几次代码后,在查看Moment文档之前,我找不到任何明显的问题。
.endOf()方法会改变日期,也就是更改您调用它的时刻对象的日期:
通过将原始时刻设置为单位时间的结尾来突变原始时刻。
所以当你在这里调用那个方法时:
var endDate = date1.endOf('month');
它正在改变date1
,这意味着它会修改date1
并更改其时间。实际上,看起来几乎所有时刻的方法都会改变当下的对象。关于为什么API设计不佳,有一个discussion on Github。
在解决您的具体问题方面,这是个人风格偏好。我认为在将对象传递给函数之前强制用户克隆对象是不可取的。所以我会克隆函数内部传递的那一刻:
function getlastDayofMonth(dayName,date1) {
var endDate = date1.clone().endOf('month');