我无法从原型函数访问私有变量(或参数)。拿这个代码:
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();
如果函数是在de object中定义的,那么它是有效的:
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
。
你能想出更好的方法吗?
答案 0 :(得分:1)
这可以在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;
唯一的限制是你希望能够访问私有数据的任何东西都要在IIFE中定义,你以后不能再来,并为Foo的原型添加一个方法。虽然,如果你对性能有所了解,你不应该无论如何都要改变原型。