0

http://jsfiddle.net/ZLH7J/1/

下面显示的 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();

​</p>

4

4 回答 4

1

Since you are using both as a constructor, format them as such:

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();

The reason it wasn't working for you is b/c "first" is created as a local varaible, and is deleted after execultion. Init isn't being called until after the execution of the constructor has finished

于 2012-08-14T13:07:56.673 回答
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,最后返回一个对象,其中包含应该通过结果对象(作为方法)可用的那些函数。

于 2012-08-14T13:07:06.807 回答
1

在您的第二个示例中,如果您注释掉“init”中的调用,this.first()那么您将收到“成功”消息。

第一个版本不起作用,因为 JavaScript 根本不允许在正在构造的对象中对对象本身进行引用。只是没有办法做到这一点。

第二个有效(对“first”的简单引用有效)因为“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声明。

于 2012-08-14T13:04:04.780 回答
1

你需要明白两点:

1) JavaScript 不会this像 Java 那样自动插入,因此first()调用只会通过词法范围查找 的定义first,它不会查看this对象。因此,调用first()应该可以工作,但this会绑定到您可能期望的其他内容first

2) 构造函数中的局部变量不会成为构造对象的成员。

于 2012-08-14T13:05:48.927 回答