javascript - 如何从 Javascript 原型(prototype)方法获取私有(private)变量

标签 javascript prototype

我无法从原型(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/

相关文章:

javascript - <g> 元素不适应 Firefox 上的 <svg>

javascript - 一个对象的原型(prototype)可以改成另一个对象吗?

javascript - 'require(...)' 是常见的 javascript 模式还是库函数?

javascript - 了解 javascript 中的原型(prototype)设计和 oops 实现

javascript - JavaScript 中 Function.prototype 和 Object.prototype 的区别

使用原型(prototype)时 JavaScript 对象会被覆盖

javascript - 在函数原型(prototype)中使用 _.extend

javascript - 通过 POST 将 Angular 变量传递到 Express 后端

javascript - IntelliJ IDEA 中的 P5.js?

javascript - 使用javascript验证注册表单