如何在对象实例中使用构造函数的私有方法(禁用call/apply/bind)
如何让实例调用构造函数内的私有函数
首先先修正你代码里的两个小问题:
beta方法里的alert(c)应该改成alert(this.c),否则会因为找不到变量c报错- 创建实例的代码应该是
var obj1 = new alpha();,你写的alp...是拼写不全的问题
接下来回到你的核心问题:因为ceta是构造函数alpha内部用var声明的函数,它的作用域仅限于alpha函数内部,实例本身是无法直接访问这个私有函数的。要让obj1在不使用call/apply/bind的情况下调用它,我们可以利用闭包的特性,通过构造函数内的公开方法间接调用私有函数,具体有两种实用方式:
方式一:新增公开方法调用私有函数
直接在alpha构造函数里给实例挂载一个公开方法,这个方法内部去调用ceta,这样实例就能通过这个公开入口触发私有函数:
<html> <head></head> <body> <script> function alpha(){ this.a = 10; this.b = 20; this.beta = function(){ this.c = 30; alert(this.c); // 修正后的代码 } var ceta = function(){ alert ("hi!"); } // 添加专门调用ceta的公开方法 this.invokeCeta = function() { ceta(); } } var obj1 = new alpha(); obj1.invokeCeta(); // 执行后会弹出"hi!" </script> </body> </html>
方式二:复用现有公开方法调用私有函数
如果你不想新增方法,也可以修改现有的beta方法,在它内部加入对ceta的调用,这样调用obj1.beta()时就会顺带触发私有函数:
<html> <head></head> <body> <script> function alpha(){ this.a = 10; this.b = 20; this.beta = function(){ this.c = 30; alert(this.c); ceta(); // 在现有方法内调用私有函数 } var ceta = function(){ alert ("hi!"); } } var obj1 = new alpha(); obj1.beta(); // 会先弹出30,紧接着弹出"hi!" </script> </body> </html>
原理说明
构造函数内部的公开方法(比如invokeCeta或修改后的beta)和私有函数ceta处于同一个作用域,它们可以直接访问到ceta。而这些公开方法被挂载到了实例obj1上,所以实例可以通过调用这些公开方法间接触发私有函数,全程不需要用到call/apply/bind。
需要明确的是:你永远没办法让实例直接访问ceta,因为它是构造函数的私有变量,只能通过闭包的方式,借助同一作用域内的公开方法来间接调用。
内容的提问来源于stack exchange,提问作者Deadpool
相关产品推荐
相关产品推荐

