我正在用javascript学习模式,遇到了原型模式,它非常适合在对象中设置默认状态。
示例:我正在使用PrototypePattern创建Session。带有一些默认状态和方法(例如Jwt Sign and Check),从数据库,实例名称等获取用户帐户详细信息,以便在对象初始化之后,您将具有一些默认处理程序和它们的配置,这些配置仅适用于给定的请求或用户。
代码:
'use strict'
/*
IMPORT'S.
*/
import _ from 'underscore' // npm; utility module.
import Jwt from 'jsonwebtoken' // npm: json webtoken library.
/*
PRISMA
*/
import { prisma } from '~prisma' // prisma: database library.
/*
DYNA
*/
import Cache from '~dyna_modules/Cache' // custom: redis cache library.
/*
OBJECT
*/
export default async function Session({ name, request }) {
// error handling.
try {
// properties.
this.name = name ? name.toUpperCase() : name
console.log(this, this.prototype)
// only proceed if request is defined
// else report failure.
if (!_.isEmpty(request) && _.isObject(request)) {
// only proceed if headers
// authorization is provided
// else report failure.
if (request.headers && request.headers.authorization) {
// local variable.
let _JwtCheck
// variable assignment.
_JwtCheck = this.Jwt.Verify(request.headers.authorization)
// verify given jwt if is
// valid token or not.
if (!_.isEmpty(_JwtCheck) && !(_JwtCheck instanceof Error)) {
// local variable.
let _Session
// variable assignment.
_Session = await this.Account({ '$exists': true }).Cache().includes(request.headers.authorization)
// if account with given authorization
// exist than get user details
if (_Session && !(_Session instanceof Error)) {
// update instance with
// session detail's.
this.account = _JwtCheck
this.chainValue = _Session
// report failure.
} else return _Session instanceof Error ? _Session : new Error('Auth token not found in Session. Please login again')
// report failure.
} else return _JwtCheck instanceof Error ? _JwtCheck : new Error('Expected account details but return undefined')
// report failure.
}
}
// return instance
return this
} catch (error) {
// report failure.
return error
}
}
/*
PROTOTYPE
*/
Session.prototype = {
// properties.
'name': 'SESSION',
'chainValue': null,
'account': null,
'configuration': {
'expireIn': '2 days'
},
// helper method's.
'includes': (__include) => { this.chainValue = this.chainValue.includes(__include); return this },
// jwt handler for handling jwt
// token's etc.
'Jwt': {
'Sign': async (__account) => {
// local variable.
let _SignedToken, _UserSessionCache
console.log(this) // undefined
// Please note that this is undefined here
// and we need some configuration values like
// this.name and this.configuration.expireIn
// but you can't because this is undefined for
// that i referenced them directly to prototype
// this.name 'became' Session.prototype.name
// this.configuration 'became' Session.protype.configuration
// sign toke and update cache.
_SignedToken = Jwt.sign(__account, process.env.TRUCKPE_SECRET, { 'expiresIn': Session.prototype.configuration.expireIn });
_UserSessionCache = await Cache({ _id: `${Session.prototype.name}::${__account._id}` })
_UserSessionCache = _UserSessionCache && _UserSessionCache.Cache && typeof _UserSessionCache.Cache === typeof [] ? _UserSessionCache.Cache : null
_UserSessionCache = _.isArray(_UserSessionCache) && !_UserSessionCache.includes(_SignedToken) ? [ ..._UserSessionCache, _SignedToken ] : [_SignedToken]
// run cache again.
_UserSessionCache = await Cache({ '_id': `SESSION::${__account._id}`, 'whatToCache': _UserSessionCache, 'options': { 'expireIn': Session.prototype.configuration.expireIn } })
// on successful cacheUpdate reply to
// client.
if(!_.isEmpty(_UserSessionCache) && !(_UserSessionCache instanceof Error)) {
// update chainValue.
Session.prototype.chainValue = Session.prototype.account = __account
// register jwt token and
// return.
return _SignedToken
// report failure.
} else return _UserSessionCache instanceof Error ? _UserSessionCache : new Error('Expected Cache update for session but return was undefined')
},
'Verify': async (__token) => {
// error handling.
try {
// local variable.
let _JwtVerify
// variable assingment.
_JwtVerify = await Jwt.verify(__token, process.env.TRUCKPE_SECRET);
// if _jwtVerify contain's error
// than report failure else return
// this.
if (!_.isEmpty(_JwtVerify) && !(_JwtVerify instanceof Error)) {
// update chain value.
Session.prototype.chainValue = Session.prototype.account = _JwtVerify
// return instance.
return Session.prototype
// report failure.
} else return _JwtVerify instanceof Error ? _JwtVerify : new Error(`Caught exception JwtVerify return undefined`)
} catch (error) {
// report failure.
return error
}
}
},
// account handler for handling
// user account in prisma
'Account': async (options) => {
// error handling.
try {
// local variable.
let _id, _getAccountDetail
// re-assingment.
_id = typeof this.chainValue === typeof {} ? this.chainValue['_id'] : typeof this.chainValue === typeof 'String' ? this.chainValue : this.account ? this.account['_id'] : null
// variable assingment.
_getAccountDetail = options && options.$exists ? await prisma.account({ _id }).$exists() : await prisma.account({ _id })
// if getting account detail
// contain's error than report
// failure else return account
// detail's.
if (_getAccountDetail && !(_getAccountDetail instanceof Error)) {
// update chainValue.
this.chainValue = _getAccountDetail
// return instance.
return this
} else return _getAccountDetail instanceof Error ? _getAccountDetail : new Error(`Caught exception while fetching account details from database`)
} catch (error) {
// report failure.
return error
}
},
// cache handler for caching session
// and other details.
'Cache': async (options) => {
// error handling.
try {
// local variable.
let _id, _getCache
// variable re-assingment.
_id = typeof this.chainValue === typeof {} ? this.chainValue['_id'] : typeof this.chainValue === typeof 'String' ? this.chainValue : this.account ? this.account['_id'] : null
// variable assingment.
_getCache = options && options.save ? await Cache({ '_id': `${this.name}::${_id}`, 'whatToCache': this.chainValue }) : await Cache({ '_id': `${this.name}::${_id}` });
// if getting cache contains' error
// than report failure.
if (!(_getCache instanceof Error)) {
// update chainValue.
this.chainValue = _getCache
// return instanceof
return this
// report failure
} else return _getCache
} catch (error) {
// report failure.
return error
}
}
}
问题1:
let _Session = new Session({ request })
console.log(_Session) // { account: null, name: undefined }
console.log(_Session.prototype) // undefined why ?
问题2。
_Session.Jwt.Sign({ username: 'bla', 'email': 'lost@stackoverflow.com' })
如果您运行上述代码并在Session.prototype.Jwt.Sign中执行console.log(this),您将收到未定义的信息 我已在代码中评论问题。我想要的只是将原型属性和方法用作默认属性,但仍在Jwt中。签名,您总是会丢失“ this”?