mongoDB를 쓰기위하여 mongoose를 이용해서 코딩을 진행하고 있었다.
강의를 따라 가던중 스스로 es5문법을 es6로 바꿔 가면서 진행하였다 (var -> let, const, function -> () => {} . . )
그러던중 아래의 소스에서 undefined 를 return 을 하는 에러가 일어났다.
userSchema.methods.generateToken = (cb)=> {
const user = this;
const token = jwt.sign(user._id.toHexString(), 'secretToken');//
user.toekn = token;
user.save((err, user) => {//DB에 save한다음에 변경된 user model을 return 해줘야한다.
if (err) return cb(err);
return cb(null, user);
})
}
그리고 아래와 같이 arrow function 을 function표현식으로 변경해주니 문제는 바로 해결되었다.
userSchema.methods.generateToken = function(cb) {
const user = this;
const token = jwt.sign(user._id.toHexString(), 'secretToken');//
user.toekn = token;
user.save((err, user) => {//DB에 save한다음에 변경된 user model을 return 해줘야한다.
if (err) return cb(err);
return cb(null, user);
})
}
원인은 무엇일까?
답은 function표현식과 arrow function은 단순히 축약형의 개념이 아닌 다른점이 있는 표현식이라는것이다.
그것은 바로 arrow function이 function과는 다르게 this 를 bind하지 않는다는 점이다.
function 표현의 축약형이라고 생각하고 있었지만 사실은 큰 차이점이 있었다는 점이다.
항상 익명이며, this를 바인딩 하지 않기에 이번에 쓰려고 하는 methods에는 적용되지 않는것이었다.
위의 예제를 보면 알겠지만
arrow function은 this를 binding하지 않기에 this.i에서 undefined 를 return 한다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/애로우_펑션