我无法从原型(prototype)函数访问私有(private)变量(或参数)。采取这段代码:
function My_controller(url) {
this.list = [1, 2, 3];
}
My_controller.prototype.order_list = function() {
console.log("url: ", url);
this.list.push(this.list.splice(0, 1)[0]);
console.log(this.list);
}
var ct = new My_controller("http://");
ct.order_list();
如果函数是在对象内部定义的,它就可以工作:
function My_controller(url) {
this.list = [1, 2, 3];
this.order_list = function() {
console.log("url: ", url);
this.list.push(this.list.splice(0, 1)[0]);
console.log(this.list);
}
}
var ct = new My_controller("http://");
ct.order_list();
同时这并不是优化代码的最佳选择,不是吗? 所以我想知道为什么无法获取该变量以及如何解决这个问题?
我知道一种选择是将其保存在其中,例如:
function My_controller(url) {
this.list = [1, 2, 3];
this.url = url;
}
然后访问this.url
,而不是 url
.
你能想出更好的方法来做到这一点吗?
最佳答案
这可以在 ES 6 中完成,但我仍然认为除了模块级别之外,它基本上没有必要:
const Foo = (() => {
let privateData = new WeakMap();
return class {
constructor () {
privateData.set(this, {
hidden: 'bar'
});
}
// this is a prototype function, we could equivalently define
// it outside the class definition as Foo.prototype.getPrivate
// and it would be the same
getPrivate () {
return privateData.get(this).hidden;
}
}
})();
console.log(new Foo().getPrivate()); // logs 'bar'
WeakMap 的重要性:
它允许任意对象作为键,但这些键是弱保留的:它们不计为引用,以防止键对象被垃圾收集。返回类后,其定义的 IIFE 外部的代码将无法访问 privateData
。请参阅this了解更多信息。
请注意,这不一定会破坏继承,具体取决于您的操作方式:
class Baz extends Foo {
constructor () {
super(); // all good thanks to super
}
}
// using non ES-6
function Foo () {
privateData.set(this, {...});
}
Foo.prototype.getPrivate = function() {
return privateData.get(this);
});
function Bar() {
Foo.call(this); // fine here
}
Bar.prototype = Foo.prototype;
唯一的限制是,您希望能够访问私有(private)数据的任何内容都必须在 IIFE 中定义,您不能稍后再向 Foo 的原型(prototype)添加方法。不过,如果您那么关心性能,那么无论如何您都不应该随意更改原型(prototype)。
关于javascript - 如何从 Javascript 原型(prototype)方法获取私有(private)变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40175008/