OOP。从方法内部调用方法

时间:2011-11-15 01:04:37

标签: javascript

如何从类中的函数调用类方法?我的代码是:

var myExtension = {

    init: function() {
        // Call onPageLoad
    },  

    onPageLoad: function() {  
        // Do something    
    },

}  

我试过......

onPageLoad();

...来自init方法,但它说没有定义。

我没跟谷歌好运,因为我不太了解所使用的语法。我在网上找到的所有JS OOP示例都采用不同的格式。我使用Mozilla格式进行扩展开发。

4 个答案:

答案 0 :(得分:7)

调用当前方法的对象可通过特殊变量this获得。每次在对象上调用方法时,this都会在方法中引用该对象。

var myExtension = {

    init: function() {
        this.onPageLoad();
    },  

    onPageLoad: function() {  
        // Do something    
    },

};

this总是引用调用对象而不是函数定义的对象或是属性。

value = 'global';
var ob0 = {
        value: 'foo',
        val: function() {
            return this.value;
        },
    },
    ob1 = {value: 'bar'},
    ob2 = {value: 'baz'};

ob0.val(); // 'foo'
ob1.val = ob0.foo;
ob1.val(); // 'bar'
ob0.val.call(ob2); // 'baz'

var val = ob0.val;
val(); // 'global'

在最后一种情况下,val作为自由函数(一个未绑定到对象的函数,即不是方法)执行,在这种情况下this取值window执行中的全局对象(Web浏览器中为val)。全局变量实际上是全局对象的属性,因此val()返回'global'(名为value的全局变量的值)。由于全局变量实际上是全局对象的属性,因此您可以将自由函数视为实际上是全局对象的方法。从这个角度来看,最后两行(在全局范围内执行时)相当于:

window.val = ob0.val;
window.val();

这个观点并不完全符合作用域的现实,尽管你只会注意到函数内部的差异。在函数中,window.val = ...将创建全局,而var val则不会。

value = 'global';
var ob0 = {
        value: 'foo',
        val: function() {
            return this.value;
        },
    };

function lcl() {
    var val = ob0.val; // doesn't set a global named `val`
    return val(); // 'global'
}
lcl(); // 'global'
val(); // error; nothing named 'val'

function glbl() {
    window.val = ob0.val; // sets a global named `val`
    return window.val();  // 'global'
}
glbl(); // 'global'
val(); // 'global'

有关上面使用的call方法的更多信息,请参阅MDN的参考页面。有关this变量的更多信息,请参阅“JavaScript “this” keyword”和“How does “this” keyword work within a JavaScript object literal?

答案 1 :(得分:6)

假设您已经像这样调用了init

myExtension.init();

然后它应该是:

init: function() {
    // before
    this.onPageLoad();
    // after
}

但是在Javascript函数中实际上并没有绑定到对象,你可以在任何其他对象上调用任何函数,如下所示:

myExtension.init.call(anotherObject); // or
myExtension.init.apply(anotherObject);

在此示例中,this中的init将为anotherObject,但未定义onPageLoad。如果要支持这种用法,则必须手动引用初始对象:

init: function() {
    // before
    myExtension.onPageLoad();
    // after
}

答案 2 :(得分:2)

在Javascript中,您需要明确提及this

this.onPageLoad()

对于其他成员变量也是如此(请记住,在Javascript方法中只是恰好是函数的成员变量)

this.memberVariable

答案 3 :(得分:0)

您是否考虑过关闭?

例如:

var myExtension = ( function() {

    var me = {};

    var private_thingy = "abcDEFG123";


    var onPageLoad = function() {
        // do page loading business
        alert( private_thingy );
    }
    me.onPageLoad = onPageLoad;


    var init = function() {
        onPageLoad();
    }
    me.init = init;


    return me;

})();

///////////////

myExtension.private_thingy = "DIDDLED!";
// will NOT modify the private_thingy declared within the closure

myExtension.init(); // will work fine.

您在闭包中定义的任何内容都始终在闭包中可用,并且在小心实施时将产生对象用户无法访问的私有成员。只有您明确导出的成员(例如me.xxx = xxx行)才公开发布。

因此,当onPageLoad执行时,“abcDEFG123”将显示在警报中,“DIDDLED!”。该对象的用户可以使用点运算符修改属性,直到奶牛回家为止;然而,闭包不公开的内容永远不会被修改:即使用户在公共接口上重新分配函数,从闭包内调用private函数也总是指向闭包中定义的函数。

重要的一点是:它通过不断使用这个来解开你(除非你真的想要使用它;保存你的手指以进行更重要的打字!)。

试一试。并看看Crockford的 Javascript:The Good Parts