如何从Javascript

时间:2016-10-21 11:04:49

标签: javascript prototype

我无法从原型函数访问私有变量(或参数)。拿这个代码:

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

你能想出更好的方法吗?

1 个答案:

答案 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的原型添加一个方法。虽然,如果你对性能有所了解,你不应该无论如何都要改变原型。