部分暴露模块安全问题,签名中的默认值
partial revealing module security question, default values in signature
用 ES6 语法绕过揭示模块模式,默认变量的状态似乎依赖于在函数中包含尾随 ()(调用)。
但是,想知道如何访问函数主体中的那些下划线变量,一些令人迷惑的事情似乎以几种不同的变体继续进行。
通过 RM 模式的几次半生不熟、记忆犹新的迭代调查更多内容;它是否必须完全是一个 IIFE,或者只是独立启动它,但随后它演变成查看 _x、_y 和 _z 的访问方式。
添加尾随 ()
后错误消失,但 _._x
接受值的行为仍然存在。应该吗?
在所有这些情况下,是否可以使用 ES6 语法的变体将默认值添加到模式中?
const _ = function (_x = 'fish', _y = 'chicken', _z = 'beef') {
// console.log(_x)
_x
_y
_z
return {
// _x,
// _y,
// _z,
get x() { return this._x },
set x(value) { this._x = value }
}
}() // if you invoke it isn't broken per se., but what is the state of revealing module vars?
// _()
let x
_._x = 'fish-ly' // strongly discouraged, but why does it sort of work?
console.log(x)
x = 'tartwell'
console.log(x)
console.log(_._x) // supposed to be private?
console.log(_._x)
x = 'o.m.g'
console.log(x)
console.log(_._x) // gives fishly
console.log(_.x) // no change but gives undefined
console.log(_.x) // no change but gives undefined
_.x[_._x] // TypeError: Cannot read property 'fishly' of undefined
console.log('x', _.x) // with call () trailing function reinstated log shows x was assigned in the statement above
// _.x = 'leafy greens'
console.log(_.x)
Remaining Question: When _.x[_._x]
fires do we get a value for _.x
? From the discussion below, the object appears to have taken on a property. But this syntax is not a complete assignment, and if it were it would be a value from the right side. What's happening here?
您已将 _
定义为函数。作为对象的函数可以分配给它们任意的键值对(不幸的是)。所以
_._x = 'fish-ly'
将 属性 分配给 单函数对象 的 _x
属性(任何希望引用 _._x
). 闭包范围变量(不是属性)_x
、_y
、_z
仍然正确封装(它们只能通过您的 _
函数故意公开的内容进行更改和查看),但在调用 _
函数之前不会创建它们。
在您的代码段中,您从未调用过 _
,因此为了更清楚地了解完全相同结果的情况,您不妨将 _
替换为一个名为{}
:
const obj = {};
let x;
obj._x = 'fish-ly' // strongly discouraged, but why does it sort of work?
// because it's just a key-value pair on an object
console.log(obj._x) // which are public
console.log(obj.x) // no change but gives undefined
// because the only property is "_x", not "x"
调用该函数后,将根据需要保护刚刚创建的闭包变量。
Remaining Question: When _.x[_._x]
fires we get a value for _.x. From the discussion below, the object appears to have taken on a property. But this syntax is not a complete assignment, and if it were it would be a value from the right side. What's happening here?
允许出现不执行任何操作的独立表达式。例如:
const obj = { prop: 'val' };
obj.prop;
NaN;
window.location;
最后 3 行 没有做任何有用的事情,但解释器确实将它们解析为表达式(在丢弃它们之前,因为没有对它们进行任何处理)。同样,使用独立行
_.x[_._x]
解释器尝试将其解析为表达式。如果它可以被评估为一个表达式(并且所述解析不会抛出错误),那么该行上的语句将被认为是完整且有效的(尽管没有用),并且解释器将移至下一行.
但是将 _.x[_._x]
作为表达式求值失败,因为它等价于:
_.x[_._x]
_.x['fish-ly']
// _.x is undefined, so:
undefined['fish-ly']
并且尝试访问 undefined
的任何 属性 将抛出:
undefined['fish-ly']
如您所见,错误消息与您的代码段中的错误消息相同。
用 ES6 语法绕过揭示模块模式,默认变量的状态似乎依赖于在函数中包含尾随 ()(调用)。
但是,想知道如何访问函数主体中的那些下划线变量,一些令人迷惑的事情似乎以几种不同的变体继续进行。
通过 RM 模式的几次半生不熟、记忆犹新的迭代调查更多内容;它是否必须完全是一个 IIFE,或者只是独立启动它,但随后它演变成查看 _x、_y 和 _z 的访问方式。
添加尾随 ()
后错误消失,但 _._x
接受值的行为仍然存在。应该吗?
在所有这些情况下,是否可以使用 ES6 语法的变体将默认值添加到模式中?
const _ = function (_x = 'fish', _y = 'chicken', _z = 'beef') {
// console.log(_x)
_x
_y
_z
return {
// _x,
// _y,
// _z,
get x() { return this._x },
set x(value) { this._x = value }
}
}() // if you invoke it isn't broken per se., but what is the state of revealing module vars?
// _()
let x
_._x = 'fish-ly' // strongly discouraged, but why does it sort of work?
console.log(x)
x = 'tartwell'
console.log(x)
console.log(_._x) // supposed to be private?
console.log(_._x)
x = 'o.m.g'
console.log(x)
console.log(_._x) // gives fishly
console.log(_.x) // no change but gives undefined
console.log(_.x) // no change but gives undefined
_.x[_._x] // TypeError: Cannot read property 'fishly' of undefined
console.log('x', _.x) // with call () trailing function reinstated log shows x was assigned in the statement above
// _.x = 'leafy greens'
console.log(_.x)
Remaining Question: When
_.x[_._x]
fires do we get a value for_.x
? From the discussion below, the object appears to have taken on a property. But this syntax is not a complete assignment, and if it were it would be a value from the right side. What's happening here?
您已将 _
定义为函数。作为对象的函数可以分配给它们任意的键值对(不幸的是)。所以
_._x = 'fish-ly'
将 属性 分配给 单函数对象 的 _x
属性(任何希望引用 _._x
). 闭包范围变量(不是属性)_x
、_y
、_z
仍然正确封装(它们只能通过您的 _
函数故意公开的内容进行更改和查看),但在调用 _
函数之前不会创建它们。
在您的代码段中,您从未调用过 _
,因此为了更清楚地了解完全相同结果的情况,您不妨将 _
替换为一个名为{}
:
const obj = {};
let x;
obj._x = 'fish-ly' // strongly discouraged, but why does it sort of work?
// because it's just a key-value pair on an object
console.log(obj._x) // which are public
console.log(obj.x) // no change but gives undefined
// because the only property is "_x", not "x"
调用该函数后,将根据需要保护刚刚创建的闭包变量。
Remaining Question: When
_.x[_._x]
fires we get a value for _.x. From the discussion below, the object appears to have taken on a property. But this syntax is not a complete assignment, and if it were it would be a value from the right side. What's happening here?
允许出现不执行任何操作的独立表达式。例如:
const obj = { prop: 'val' };
obj.prop;
NaN;
window.location;
最后 3 行 没有做任何有用的事情,但解释器确实将它们解析为表达式(在丢弃它们之前,因为没有对它们进行任何处理)。同样,使用独立行
_.x[_._x]
解释器尝试将其解析为表达式。如果它可以被评估为一个表达式(并且所述解析不会抛出错误),那么该行上的语句将被认为是完整且有效的(尽管没有用),并且解释器将移至下一行.
但是将 _.x[_._x]
作为表达式求值失败,因为它等价于:
_.x[_._x]
_.x['fish-ly']
// _.x is undefined, so:
undefined['fish-ly']
并且尝试访问 undefined
的任何 属性 将抛出:
undefined['fish-ly']
如您所见,错误消息与您的代码段中的错误消息相同。