如果我通过new constructor()
调用生成一个对象,则调用如下对象:
function constructor(){
function privateFn(){
console.log('this is private');
}
this.publicFn = function(){
console.log('this is public');
}
function doSomething(){
privateFn();
publicFn();
}
console.log(this.publicFn ? "exists" : "does not exist"); // logs exists
doSomething(); //throws an error -> publicFn() is not this.publicFn().
}
new constructor();
所以问题是,有没有任何方法可以在没有this.
部分的情况下使其可访问?即使没有this.
,我的IDE(netbeans)似乎也能识别它,尽管这并不一定意味着什么,但它让我想知道,是否有可能以某种方式将publicFn()
引用为函数,而不是对象的属性?也许用不同的方式构建它?
EDIT:目标是创建一个具有new
构造函数的私有和公共方法的对象,但同时允许构造函数本身以及对象的所有方法调用不带this.
前缀的公共方法。
BEKIM BACAJ特别版
专门为你更新了这一部分,只是为了向你展示我的意思。困扰我的不是console.log,也不是对doSomething
的调用或对象真正创建后出现的任何其他方法。尽管如此,它仍然无法访问,现在我已经看到了原因的答案,这是有道理的。上下文this
与私有方法不同,或者更确切地说,构造函数中的函数将this
设置为window,因此它们的上下文this
与它们试图调用的公共方法不同。Phyloggenesis建议的模式是我正在寻找的,它符合需求。
function constructor(){
function privateFn(){
console.log('Call to privateFN succesful');
console.log('------------------------------------------------------------------------------------');
}
function doSomething(){
console.log('Executing: doSomething;');
//I want to be able to access both private and public methods here (which i can)
//I want to be able to access them the same way (which I cannot).
privateFn(); //works
publicFn(); //error
//Read NOTE1 below.
}
this.callDoSomething = function(){
console.log('Call to callDoSomething succesful');
console.log('------------------------------------------------------------------------------------');
//made just so that you can access doSomething from the outside to test.
doSomething();
};
this.publicFn = function(){
console.log('Call to publicFN succesful');
console.log('------------------------------------------------------------------------------------');
};
//.... many more methods (we are talking hundreds)
//.... some of them are public, some are private
//.... some are resutls of calling functions that return functions from other files (collaborative work),
//.... these might be public or private, which we achive like so:
//.... var externalModule = extrenalModuleInitializer(this);
//.... as you can imagine this externalModuleInitializer function can either:
//.... A) PRIVATE: return a function, making this externalModule variable a private method
//.... B) PUBLIC: do stuff with the `this` object that was passed, adding public methods to it
//.... So since I do not know if certain parts of this object will be private or public, i need
//.... a way to access them in the same way in order to make the coding easier.
}
console.clear();
var a = new constructor();
a.publicFn();
a.callDoSomething();
我认为你真正追求的是模块模式:
function MyConstructor() {
var publicFn = function () {
console.log('this is public');
}
var privateFn = function () {
console.log('this is private');
}
var doSomething = function () {
privateFn();
publicFn();
}
doSomething();
return {
publicFn: publicFn
};
}
请注意,您是如何返回一个"公共"可访问方法的列表的,但没有任何内部引用this
。
这里就是一个例子。
我不确定它是否符合您的需要,但这(最后的return
语句)公开了方法:
function constructor(){
function privateFn(){
console.log('this is private');
}
this.publicFn = function(){
console.log('this is public');
}
function doSomething(){
privateFn();
publicFn();
}
return{
publicFn: this.publicFn
}
}
你可以这样称呼它:
var constr = constructor();
constr.publicFn();
this
是对一个对象的引用,该对象将基于函数描述的原型创建(但尚未存在),因此在声明public方法时不能避免this
关键字。从技术上讲,你可以在构造函数之外定义这个函数,如下所示:
function publicFn(){}
function constructor() {
....
}
var obj = new constructor();
obj.publicFn = publicFn;
但是,恐怕没有多大意义
为了设计这个响应,我依赖Yves M.在本次讨论中提供的"使用自调用函数和调用"技术
var Constructor = (function (){
function Constructor (){}
function privateFn(){
console.log('this is private');
}
Constructor.prototype.publicFn = function(){
console.log('this is public');
}
Constructor.prototype.doSomething = function(){
return privateFn.call(this);
}
return Constructor;
})();
var Constructor = new Constructor();
Constructor.publicFn();
Constructor.doSomething();
注意:即使空的构造函数方法看起来什么都不做,但它对代码的无错误运行至关重要。否则,您将看到一条错误消息:"无法读取未定义的属性‘prototype’",
privateFn()方法之所以被隐藏,是因为它不是constructor对象原型的一部分。此外,我能够在不提供this参数的情况下使privateFn的调用方法工作,但它是调用方法签名的一部分。根据文档,忽略提供这会导致一个null和未定义的参数被"…替换为全局对象,原始值将转换为对象。">