给定以下 API:
SomeAPI = (function() {
var secretKey = 'passw0rd',
foo = 'foo',
bar = 'bar';
return {
use : function(callback) { /* Provide the API to the callback */ }
};
})();
它由几个值组成,最重要的是通过其 use()
公共(public)方法使用,该方法允许用户通过回调使用 API。
回调可以通过以下两种方式之一访问 API:
1) 通过这个
callback
是 call
编辑或 appl[i]
编辑。使用 this
即可使用 API:
SomeAPI.use(function() {
doStuffWith(this.foo);
});
2) 通过参数
callback
只需使用包含 API 的参数进行调用。使用给定参数完成 API 的使用:
SomeAPI.use(function(api) {
doStuffWith(api.bar);
});
<小时/>
我见过这两种模式的使用。两者之间有什么实际区别吗?其中之一有可能,而另一个则不行?
最佳答案
Is there any practical difference between the two? Something possible with one but not the other?
我确信有很多差异,但我将详细介绍我所能知道的最重要的差异。
对于第一个示例,将变量分配给私有(private)对象,然后将该私有(private)对象分配给回调的 this
值。
这样做的好处是我们实际上传递了对私有(private)对象的引用,因此我们可以更改该对象。
这样做的坏处是,我们实际上传递了对私有(private)对象的引用,因此用户可以随意更改该对象,这从来都不是一件好事。
SomeAPI = (function() {
var private = {};
private.secretKey = 'passw0rd';
private.foo = 'foo';
private.bar = 'bar';
return {
use : function(callback) { callback.call(private); }
};
})();
console.log(SomeAPI.private);
// undefined
SomeAPI.use(function(){
console.log(this.secretKey, this.foo, this.bar);
// passw0rd foo bar
console.log(this.constructor);
// Object() { [native code] }
console.log(this);
// Object {secretKey: "passw0rd", foo: "foo", bar: "bar"}
this.hello = 'world';
this.foo = 'bar';
this.bar = 'foo';
});
SomeAPI.use(function(){
console.log(this.secretKey, this.foo, this.bar, this.hello);
// passw0rd bar foo world
console.log(this);
// Object {secretKey: "passw0rd", foo: "bar", bar: "foo", hello: "world"}
});
让我们评估一下这向我们展示了什么。
- 私有(private)对象实际上是私有(private)的。
this
指的是私有(private)对象。this
包含所有私有(private)属性。- 对私有(private)对象的任何更改都会保留到下一次 API 调用。
对于第二个示例,我们将每个私有(private)属性的值传递给回调。
此方法的优点是之前方法的失败。此方法会锁定所有内容,因此只有您明确允许更改/访问的内容才能更改/访问。
此方法的缺点是您被锁定在 API 定义的内容中。
OtherAPI = (function() {
var secretKey = 'passw0rd',
foo = 'foo',
bar = 'bar';
return {
use : function(callback) { callback(secretKey, foo, bar); },
setFoo : function(val) { foo = val },
setBar : function(val) { bar = val }
};
})();
console.log(OtherAPI.foo);
// undefined
OtherAPI.use(function(secretKey, foo, bar){
console.log(secretKey, foo, bar);
// passw0rd foo bar
console.log(this.constructor);
// Window() { [native code] }
foo = 'bar';
bar = 'foo';
console.log(secretKey, foo, bar);
// passw0rd bar foo
});
OtherAPI.use(function(secretKey, foo, bar){
console.log(secretKey, foo, bar);
// passw0rd foo bar
});
OtherAPI.setFoo('bar');
OtherAPI.setBar('foo');
OtherAPI.use(function(secretKey, foo, bar){
console.log(secretKey, foo, bar);
// passw0rd bar foo
});
好的,这向我们展示了什么?
- 私有(private)属性(property)实际上是私有(private)的
- 我们只能通过提供的参数读取私有(private)属性的值。
- 对回调参数所做的任何更改不会会保留到下一次 API 调用。
- 如果我们在返回的 API 对象中定义函数来更改私有(private)属性的值,我们就可以更改各个值。这些更改确实会持续到下一次 API 调用。
最后还有一个示例,可以说是两者之间的折衷方案,如果做得正确,可以比前面的任何一个示例都更加通用。
此方法的好处是您可以保护您想要保护的内容,并选择用户访问私有(private)变量的方式。
此方法的缺点是您确实必须考虑用户可能如何尝试按顺序滥用 get 和 set 函数
OtherAPI = (function() {
var private = {};
private.secretKey = 'passw0rd';
private.foo = 'foo';
private.bar = 'bar';
private.noaccess = 'No Access!';
return {
use : function(callback) { callback.call(this); },
get : function(prop) {
if(private[prop] && prop != 'noaccess') return private[prop];
return false;
},
set : function(prop, val) {
if(private[prop] && prop != 'noaccess') return (private[prop] = val);
return false;
},
noaccess : function() { return private.noaccess }
};
})();
console.log(OtherAPI.secretKey);
// undefined
console.log(OtherAPI.get('secretKey'));
// passw0rd
OtherAPI.use(function(){
console.log(this.get('secretKey'), this.get('foo'), this.get('bar'), this.get('noaccess'), this.noaccess());
// passw0rd foo bar false No Access!
console.log(this.constructor);
// Object() { [native code] }
// The above object is actually the public scope, not the private scope
this.set('foo', 'bar');
this.set('bar', 'foo');
this.hello = 'world'; // This will be in the public scope
console.log(this.get('secretKey'), this.get('foo'), this.get('bar'), this.get('noaccess'), this.noaccess(), this.hello);
// passw0rd bar foo false No Access! world
});
OtherAPI.use(function(secretKey, foo, bar){
console.log(this.get('secretKey'), this.get('foo'), this.get('bar'), this.get('noaccess'), this.noaccess(), this.hello);
// passw0rd bar foo false No Access! world
});
这个例子向我们展示了什么?
- 和以前一样,私有(private)就是私有(private)。
this
指公共(public)对象(返回给OtherAPI的对象)- 我们现在可以设置或获取任何私有(private)属性,只要它们当前存在并且我们没有明确拒绝对该变量的访问。
- 您还可以进一步控制可以设置或检索哪些私有(private)属性以及如何进行设置或检索。
这意味着您的 API 可能比第一个示例更安全,同时比第二个示例更灵活,并且通过在 set 和 get 函数中添加安全检查,它可以与第二个示例一样安全或更安全.
最终,这一切都取决于您对 API 用户的信任程度,以及您想要保护私有(private)属性(property)的程度。
关于javascript - 通过上下文提供对 API 的访问或通过参数提供对 API 的访问有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31539056/