JavaScript私有方法

时间:2020-03-05 18:51:10  来源:igfitidea点击:

要使用公共方法创建JavaScript类,我需要执行以下操作:

function Restaurant() {}

Restaurant.prototype.buy_food = function(){
   // something here
}

Restaurant.prototype.use_restroom = function(){
   // something here
}

这样,我班的用户可以:

var restaurant = new Restaurant();
restaurant.buy_food();
restaurant.use_restroom();

我如何创建一个私有方法,该方法可以由buy_fooduse_restroom方法调用,但不能由该类的用户外部调用?

换句话说,我希望我的方法实现能够做到:

Restaurant.prototype.use_restroom = function() {
   this.private_stuff();
}

但这不起作用:

var r = new Restaurant();
r.private_stuff();

如何将private_stuff定义为私有方法,使两者都成立?

我已经读过Doug Crockford的文章几次,但似乎公共方法不能调用"私有"方法,而外部可以调用"特权"方法。

解决方案

回答

我们可以做到,但缺点是它不能成为原型的一部分:

function Restaurant()
{
    var myPrivateVar;

    var private_stuff = function()   // Only visible inside Restaurant()
    {
        myPrivateVar = "I can set this here!";
    }

    this.use_restroom = function()   // use_restroom is visible to all
    {
        private_stuff();
    }

    this.buy_food = function()    // buy_food is visible to all
    {
        private_stuff();
    }
}

回答

我们可以像下面这样模拟私有方法:

function Restaurant() {
}

Restaurant.prototype = (function() {
    var private_stuff = function() {
        // Private code here
    };

    return {

        constructor:Restaurant,

        use_restroom:function() {
            private_stuff();
        }

    };
})();

var r = new Restaurant();

// This will work:
r.use_restroom();

// This will cause an error:
r.private_stuff();

有关此技术的更多信息,请访问:http://webreflection.blogspot.com/2008/04/natural-javascript-private-methods.html

回答

在这些情况下,当我们拥有公共API并想要私有和公共方法/属性时,我总是使用模块模式。这种模式在YUI库中很流行,详细信息可以在这里找到:

http://yuiblog.com/blog/2007/06/12/module-pattern/

这确实很简单,其他开发人员也很容易理解。举个简单的例子:

var MYLIB = function() {  
    var aPrivateProperty = true;
    var aPrivateMethod = function() {
        // some code here...
    };
    return {
        aPublicMethod : function() {
            aPrivateMethod(); // okay
            // some code here...
        },
        aPublicProperty : true
    };  
}();

MYLIB.aPrivateMethod() // not okay
MYLIB.aPublicMethod() // okay

回答

模块模式的神化:揭示模块模式

整洁的小扩展,非常强大的模式。

回答

所有这些关闭将使我们付出代价。确保测试速​​度的影响,尤其是在IE中。我们会发现使用命名约定会更好。仍然有很多公司网络用户被迫使用IE6 ...

回答

如果要使用公共功能访问私有功能的全部公共和私有功能,请为这样的对象布置代码:

function MyObject(arg1, arg2, ...) {
  //constructor code using constructor arguments...
  //create/access public variables as 
  // this.var1 = foo;

  //private variables

  var v1;
  var v2;

  //private functions
  function privateOne() {
  }

  function privateTwon() {
  }

  //public functions

  MyObject.prototype.publicOne = function () {
  };

  MyObject.prototype.publicTwo = function () {
  };
}

回答

我想到了这一点:编辑:实际上,有人链接到相同的解决方案。 h!

var Car = function() {
}

Car.prototype = (function() {
    var hotWire = function() {
        // Private code *with* access to public properties through 'this'
        alert( this.drive() ); // Alerts 'Vroom!'
    }

    return {
        steal: function() {
            hotWire.call( this ); // Call a private method
        },
        drive: function() {
            return 'Vroom!';
        }
    };
})();

var getAwayVechile = new Car();

hotWire(); // Not allowed
getAwayVechile.hotWire(); // Not allowed
getAwayVechile.steal(); // Alerts 'Vroom!'