下面显示的jsFiddle和代码是两个基本上做同样事情的例子。在任一示例中尝试调用first();
或this.first();
时,都会引发未定义的错误。我可以稍后通过实例调用函数,但是在尝试使用init(){...}()
像构造函数实例化对象时则不行。我把init()放在底层以为它是一个操作顺序,但事实并非如此。这不会像我认为的那样有效。
我很想知道应该怎么做,以及为什么不能这样做。
//create and return an obj
var fishSticks = function(){
return {
first: function(){
document.getElementById('output').innerHTML="Success";
},
init: function(){
try{
first(); //err
this.first(); // also err
}catch(e){
document.getElementById('output').innerHTML=e.toString();
}
}()
}
}
//do function stuff and then return 'this'
var fishFillet = function(){
var first = function(){
document.getElementById('output2').innerHTML="Success";
}
var init = function(){
try{
first(); //err
this.first(); // also err
}catch(e){
document.getElementById('output2').innerHTML=e.toString();
}
}()
return this;
}
var test = new fishSticks();
var test2 = new fishFillet();
答案 0 :(得分:1)
在您的第二个示例中,如果您将“init”中的呼叫注释到this.first()
,则会收到“成功”消息。
第一个版本不起作用,因为JavaScript根本不允许在构造对象内对对象本身进行引用。没有办法做到这一点。
第二个工作(以及“第一个”工作的简单引用),因为“first”被声明为局部变量。局部变量是任何对象的不属性,特别是它们不是在使用new
调用函数时分配的对象的属性。这就是this.first()
不起作用的原因。
在第二个问题中,您可以通过不同的方式宣传this.first()
:
var fishFillet = function(){
this.first = function(){
document.getElementById('output2').innerHTML="Success";
}
var init = function(){
try{
this.first(); //will work
}catch(e){
document.getElementById('output2').innerHTML=e.toString();
}
}()
return this;
}
此外,对于它的价值,还有奇怪的反模式
var something = function() { ... }
没有
那么有用function something() { ... }
没有理由使用var
声明而不是function
声明。
答案 1 :(得分:1)
你需要了解两件事:
1)JavaScript不会像Java那样自动插入this
,因此first()
调用只会通过词法范围查看first
的定义,它将会查看this
对象。因此,对first()
的调用应该有效,但this
将绑定到除first
内的预期之外的其他内容。
2)构造函数中的局部变量不会成为构造对象的成员。
答案 2 :(得分:1)
怎么样......
var fishFillet = function () {
var first = function () {
document.write( 'Success' );
};
var init = function () {
first();
};
init();
return {
first: first
};
};
然后:
var ff = fishFillet(); // calls init() which calls first()
ff.first(); // call first() manually
现场演示: http://jsfiddle.net/uaCnv/
因此,首先定义所有函数,然后手动调用init
,最后返回一个包含那些应该通过结果对象可用的函数的对象(作为方法)。
答案 3 :(得分:1)
由于您将两者都用作构造函数,因此将它们格式化为:
function fishFillet(){
this.first = function(){
document.getElementById('output2').innerHTML="Success";
}
this.init = function(){
try{
this.first();
}catch(e){
document.getElementById('output2').innerHTML=e.toString();
}
}
}
var food = new fishFillet();
food.init();
它不适合你的原因是b / c“first”被创建为本地变量,并在execultion后被删除。在构造函数执行完成之后才会调用Init