为什么这个方法不能在原型中调用?

时间:2014-06-24 23:29:09

标签: javascript

我正在尝试学习如何编写更好的javascript,但我不确定为什么这不起作用。我有两个写入文本字段的方法调用。第一个工作正常,但第二个没有。为什么文本字段变量未定义通过嵌套调用?任何帮助将不胜感激:

(function () {
    var TestObj = function (logEl) {
        this.log = logEl;
    };

    TestObj.prototype = function () {
        var log1 = function (text) {
            this.log.val(text);
        };

        var log2 = function (text) {
            log1(text);
        }

        return {
            log1: log1,
            log2: log2
        };
    }();

    $(function () {
        var logEl = $("#log");
        var test = new TestObj(logEl);
        test.log1("This Works");
        test.log2("This Dosen't"); //this.log is undefined
    });
})()

3 个答案:

答案 0 :(得分:3)

在第二种情况下,正在调用log1而没有任何上下文。从log2调用时this的值将是全局对象,而不是TestObj的实例。

尝试将其更改为:

var log2 = function (text) {
    this.log1(text);
}

demo fiddle

答案 1 :(得分:2)

我认为该问题与在this中不使用log2

有关
var log2 = function (text) {
    this.log1(text);
}

一个小提琴示例:http://jsfiddle.net/y66YT/

答案 2 :(得分:1)

正如dc5和Hayes所指出的,this的值是调用对象。它是函数之前的对象:

somebutton.click();//this is somebutton
click();//nothing before click, window is assumed or throw exception in strict mode
myObject.doSomething();//this in doSomething is myObject

由于log1可通过closures获得,因此它不会立即抛出异常(log1未定义)但log1函数中的this是窗口,因为log2没有提供调用对象

要设置调用对象,您可以将代码更改为:

 log1.call(this,text);

我不喜欢扔掉包括IIFE厨房水槽在内的所有东西,因为它为每种方法都会产生不必要的closures。您可以将应用程序包装为对象文字,并在实际需要closures

的地方使用IIFE
var app ={
  testObj:function(...

log1在log2中无法通过闭包获得,但您可以使用this

来调用它
 this.log1(text);

有关原型,构造函数,继承和this的价值的更多内容可以找到here