这个'是什么?在javascript参考?

时间:2010-12-17 07:21:11

标签: javascript this

我不确定JavaScript中的这一点。我举两个例子。

你可以帮我分析一下吗?非常感谢你。

//exmp1
function f1()
{
  alert(this);
  function f2()
  {
    alert(this);
  }
  f2();
}
f1();

//exmp2
var jsn = 
{
  name : "b",
  func : function() // closure
  {
    alert(this); 
    return function()
    {
      return this;
    }
  }
}

alert(jsn.func()());

4 个答案:

答案 0 :(得分:13)

this在JavaScript中与在C ++或Java等其他语言中的不同。第一个示例中this的值始终是浏览器上的全局对象(window)。第二个示例中的this是第一个警报的jsn对象,第二个是window。这是因为this完全由决定如何调用函数,而不是它被定义的位置。

如果在调用函数时没有做任何特殊操作,this是全局对象。通过对象属性(jsn.func())调用函数时,this设置为属性来自的对象。 (但不要给人留下错误的印象,func绝不与jsn特别相关; JavaScript没有方法,只是函数; details 。)f1然后返回一个函数,该函数在最终alert内调用;由于该调用不是通过对象属性,因此将this设置为全局对象。

一些例子:

// Simple function
function foo() {
    alert(this === window);
}
foo(); // true, within the call, `this` === `window`

// Object example, and twist at the end
var obj = {
    func: function() {
        alert(this === obj);
    },
};
obj.func();    // true, within the call, `this` === `obj`
obj["func"](); // true, within the call, `this` === `obj`

var f = obj.func; // Not calling it, just getting a reference to the function
f(); // false, within the call `this` !== `obj` (`this` === `window`)

// Creating functions on the fly, returning them, and how that has
// nothing whatsoever to do with how `this` gets set:
var obj = {
    func: function() {
        return function() {
            alert("I'm a generated function");
            alert(this === obj);
        };
     }
};
obj.func()(); // alerts the "I'm a generated function", then false; `this` !== `obj`
obj.bar = obj.func();
obj.bar();    // alerts the "I'm a generated function", then true; `this` === `obj`

还有第二种方法来控制函数中的this:使用JavaScript函数的.call.apply功能:

var obj = {
    func: function() {
        alert(this === obj);
    }
};
function foo(a, b) {
    alert(this === obj); // Yes, really obj; see below
    alert(a);
    alert(b);
}
foo(1, 2);               // alerts false (`this` !== `obj`), then 1, then 2
obj.func();              // alerts true, `this` === `obj`
foo.call(obj, 3, 4);     // alerts true (`this` === `obj`), then 3, then 4
foo.apply(obj, [5, 6]);  // alerts true (`this` === `obj`), then 5, then 6

如您所见,callapply的第一个参数是在函数调用中生成this的对象。 callapply之间的唯一区别是如何指定传递给目标函数的参数:使用call,您只需在第一个参数之后提供它们;使用apply,您可以将它们作为数组提供。

最后,还有第三种方式:new关键字。 JavaScript具有构造函数的概念。构造函数的目的是创建以特定方式初始化的对象的实例。这是一个例子:

function Foo(b) {
    this.bar = b;
}
var f = new Foo();

从技术上讲,任何函数都可以用作构造函数。惯例是给出用于以大写字母开头的new名称的函数,以加强我们以特殊方式调用它们。

通过new调用函数会创建一个新的对象实例,并使该对象成为函数调用中的this值。所以

function Foo(b) {
    alert(this === window);
}
var f = new Foo(); // alerts false, `this` !== `window` (it points to the new object created for the call)
var f = Foo();     // alerts true, `this` === `window` because we didn't use `new`

如您所见,以正确的方式调用函数非常重要。如果它设计为与new一起使用,请通过new调用它;如果不是,请不要。

new不只是创建一个空白对象;创建的对象还有一些其他方面以某种方式设置。我不会在这里详细介绍,但我不想离开您认为它所做的所有的印象是创建一个新的对象实例。)

答案 1 :(得分:1)

在上一个例子中(json对象中的函数),this指的是持有该函数的json对象。

在第一个示例中,第一个this指的是持有f1的对象,它恰好是全局窗口对象。 this中的第二个f2也指向全局对象而不是f1,当您在另一个中定义了一个函数时,这是javascript 中的已知错误。

一个常见的解决方法是这个(没有双关语):

function f1() {
  alert (this);
  var that = this;
  function f2() {
    alert (that);
  }
  f2();
}

请注意,如果在json对象中定义一个函数,它仍然可以“移动”,this的上下文将会改变。例如:

var car1 = {
  color: "red",
  f: function () { alert (this.color); }
}

car1.f(); // prints "red"

var car2 = {
  color: "blue",
}

car2.f = car1.f;

car2.f(); // prints "blue"

答案 2 :(得分:1)

在JavaScript中,“this”总是指“拥有”该函数的对象,或者更确切地说,是指函数在调用时通过属性绑定到的对象。考虑这个例子:

var f = function() { alert(this); }
f(); // Alerts the "DOM window" (global) object, which
     // is implied if there is no explicit owner.
var o = {toString:function(){return "Foo!";}}
o.func = f;
o.func(); // Alerts the "Foo!" object (o) since the
          // function then belongs to it as a member.

现在关于您的具体示例,以下是发生的情况:

//exmp1
function f1() {
  alert(this);
  function f2() {
    alert(this);
  }
  f2(); // Alerts "the global object", since f2
        // is not bound to any object's property.
}
f1(); // Alerts "the global object" (probably DOM window)
      // for same reason as above.

//exmp2
var jsn = {
  name : "b",
  func : function() {
    alert(this); // Will alert the "jsn" object, since it
                 // owns the function in its "func" member.
    return function() {
      return this; // Returns whoever is calling it!
    };
  }
}
alert(jsn.func()()); // "jsn.func()" returns a function which gets
                     // called by the global "DOM window" object.

答案 3 :(得分:0)

当您使用函数作为构造函数时,它指向您正在构造的对象。

function Test() {
  this.test = true;
}

t = new Test();
alert(t.test);