部分暴露模块安全问题,签名中的默认值

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']

如您所见,错误消息与您的代码段中的错误消息相同。