如果此参数被视为私有,则不返回实例变量

时间:2018-03-07 09:15:38

标签: javascript closures

关于私有变量封装 - 通过将私有变量定义为var而不是this的属性(非私有this.private)来实现。这是使会员成为私人的最直接方式。

但是,如果返回并使用实例,则上述规则是有意义的。如果我们返回一个暴露了get / set方法的新对象。现在,将私有变量存储在this参数中仍然实现私有变量封装

当没有返回实例参数时,有没有办法可以访问实例参数?

function X(init) {
  this.private = init; 
  var that = this
  function get() {
    return that.private;
  }

  function set (tmp) {
    that.private = tmp;
  }

  return {
    get: get,
    set: set
  }
}

var tmp = new X(1);

console.log(tmp.get()) // 1

console.log(tmp instanceof X) // false

tmp.private = 20 // doesnt work as tmp isnt an instance object

console.log(x.get()) //1

x.set(20)

console.log(x.get()) //20

我是否可以访问私人,因为当this没有被退回时,this属性为<{1}}?

3 个答案:

答案 0 :(得分:0)

不,我们无法访问上的私有属性,因为您显式返回了新对象。

答案 1 :(得分:0)

使用构造函数时请考虑此示例:

function X()
{
   // Scope of X()
   var i = 1; // this variable is accessible only in this scope
   this.get = function() { return i; };
}

a = new X(); // call the constructor
console.log(a.i); // this will be undefined
a.i = 2; // even if you try to set `i` on `a`

console.log(a.get()); // the actual `i` of `a` will still be 1
console.log(a.i); // this will be two.

现在为使用返回对象的函数的示例。

function Y()
{
    // Scope of Y()
    var i = 1; // this variable is accessible only in this scope
    function get() { return i; };

    return { // now you return an object which exposes a function that returns the value of `i` of this SCOPE.
        get: get
    }
}

b = Y();

console.log(b.i); // this will be undefined
console.log(b.get()); // this will be 1
b.i = 3; // this will work
console.log(b.get()); // this will still be 1
console.log(b.i); // this will be 3

对不起,我没有足够的时间继续解释,我稍后会再回来。

您可以隐藏(隐藏)成员变量,方法是将其隐藏在范围内。

此外,在这两种方法之间,只有第一种方法可以使用this关键字。您无法在第二种方法中使用this关键字,因为其值将是窗口

答案 2 :(得分:-2)

您可以使用WeakMap实现真正的隐私 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap

WeakMaps允许您创建附加对象,您可以在其上附加任何值。 如果您无法访问定义它们的范围,则无法访问它们。

在浏览器中使用ES5

"use strict";
{
    const privacy = new WeakMap();

    function X(init)
    {
        privacy.set(this, {});

        const props = privacy.get(this);

        props.init = init;
    }

    X.prototype.setInit = function(tmp)
    {
        privacy.get(this).init = tmp;
    };

    X.prototype.getInit = function()
    {
        return privacy.get(this).init;
    };

    window.X = X;
}

在NodeJS中使用ES6类表示法

const privacy = new WeakMap();

class X
{
    constructor(init)
    {
        privacy.set(this, {});

        const props = privacy.get(this);

        props.init = init;
    }

    setInit(tmp)
    {
        privacy.get(this).init = tmp;
    }

    getInit()
    {
        return privacy.get(this).init;
    }
}

module.exports = X;