gpt4 book ai didi

javascript - Crockford 的安全对象模块

转载 作者:行者123 更新时间:2023-11-29 17:44:39 25 4
gpt4 key购买 nike

我知道有很多关于“Javascript:好的部分”的问题和文档,但我试图理解书中一句话的意思,但不太明白。在第 41-42 页中,他定义了 serial_maker 函数:

var serial_maker = function (  ) {

// Produce an object that produces unique strings. A
// unique string is made up of two parts: a prefix
// and a sequence number. The object comes with
// methods for setting the prefix and sequence
// number, and a gensym method that produces unique
// strings.

var prefix = '';
var seq = 0;
return {
set_prefix: function (p) {
prefix = String(p);
},
set_seq: function (s) {
seq = s;
},
gensym: function ( ) {
var result = prefix + seq;
seq += 1;
return result;
}
};
};

var seqer = serial_maker();
seqer.set_prefix('Q');
seqer.set_seq(1000);
var unique = seqer.gensym(); // unique is "Q1000"

然后他说:

The methods do not make use of this and that. As a result, there is no way to compromise the sequer. It isn't posible to get or change the prefix or seq except as permitted by the methods

我应该如何使用this 和/或that 来打破这种封装?我看不到

谢谢

最佳答案

考虑以下变化:

var serial_maker = function () {
return {
prefix: '',
seq: 0,

set_prefix: function (p) {
this.prefix = String(p);
},
set_seq: function (s) {
this.seq = s;
},
gensym: function ( ) {
var result = this.prefix + this.seq;
this.seq += 1;
return result;
}
};
};

现在,sequer 的预期用途如下:

var sequer = serial_maker();
sequer.set_prefix('right');
sequer.set_seq(1000);

但是,在我上面发布的版本中,您也可以这样做:

var sequer = serial_maker();
sequer.prefix = 'wrong';
sequer.seq = -500;

甚至这样:

delete sequer.prefix;

因为两个prefixseq作为 sequer 对象的属性公开,JavaScript 中的属性始终是公共(public)的。任何有权访问该对象的代码至少可以读取其属性,并且通常也可以修改它们(除非您使用 Object.defineProperty() 提供的某些功能)。

至于that : 在引入箭头函数之前,定义为方法的函数无法访问创建它们的上下文是一个非常普遍的问题。

考虑以下示例:

var ButtonInitializer = {
message: 'Hello!'

init: function() {
for (let button of document.querySelectorAll('button')) {
button.onclick = function() {
alert(this.message);
}
}
}
};

ButtonInitializer.init();

对象 ButtonInitializer在文档中搜索 <button>元素并设置它们的 onclick事件监听器以显示警报;我们的目的是显示 ButtonInitializer.message 中定义的消息.但是,如果运行上面的代码,您会发现警报是“undefined”。这是因为我们分配给 button.onclick 的函数成为按钮的方法,所以 this函数内的关键字现在将引用按钮,而不是 ButtonInitializer .

今天,我们可以用箭头函数解决这个问题:

button.onclick = () => {
alert(this.message);
}

箭头函数没有自己的 this范围,因此警报将显示 ButtonInitializer.message ,正如我们的意思。在引入箭头函数之前,这是一个常见的解决方法:

var that = this;
button.onclick = function() {
alert(that.message);
}

这种技术与闭包一起使用非常普遍,并允许有限地实现对象的方法可以访问的“私有(private)”成员,但不能直接从外部代码中看到。

关于javascript - Crockford 的安全对象模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50806580/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com