-1
  function foo(){ alert(this);}
  x=new foo();//this is equal to {foo();}//foo() is operating on the newly created object...

现在,根据this关键字的定义“this指向函数操作的当前对象”

由于上述函数对新创建的对象进行操作,因此 this 关键字指向它。现在,再次:

function foo(){
      //this function foo is an javascript object right?

 }

所以当我像这样在其中创建一个嵌套函数并在那里执行它时

 function foo(){
 function fo()
      {
       alert(this);//"this" keyword now should point to javascript function object
      }
 fo();//fo here is operating on javascript function object
}
foo();

所以现在当函数foo()执行时 this 关键字应该按照上面的定义指向函数 foo 对象。

不要这样说:“这个关键字的值取决于你如何调用一个函数”

我知道我正在简单地调用该函数,但根据上述定义,我的观点是否正确?

4

2 回答 2

1

在您的第二个示例中,警报对象将是窗口。这是因为:

  1. 您只是调用外部函数,而不是实例化它
  2. 警报值是内部函数的上下文,默认情况下是窗口。如果您将其用作构造函数,则外部函数的上下文将是实例。foo

为了详细说明第二点,如果您要运行以下代码,记录的值将是 x 的值:

 function foo() {
   var that = this;
   function fo() {
     console.log(that); //"this" keyword now should point to javascript function object
   }
   fo(); //fo here is operating on javascript function object
 }
 var x = new foo();
于 2013-01-06T08:59:13.630 回答
1

你的观点是错误的。请看我的另一个回答。

看,如果你使用new,那么this在构造函数的范围内将指向返回的对象。

var Point2D = function (x, y) {
    this.x = x;
    this.y = y;

    this.setX = function (x) { this.x = x; };
    this.setY = function (y) { this.y = y; };
};

var point1 = new Point2D(1, 5),
    point2 = new Point2D(2, 3);

point1.setX(7);
point2.setY(32);

我的嵌套函数被设置为正在创建的全新“this”的属性。

如果我在构造函数中有辅助函数:

Point2D = function (x, y) {

    function roundX () { return Math.floor(this.x); }
    function roundY () { return Math.floor(this.y); }
}

这些函数不是作为对象的属性添加的,因此this在它们内部调用window, 而不是

这就是 JS 的工作方式。

要么一个函数直接是一个对象的属性,要么你使用.call().apply()传递一个不同this的函数,或者函数使用window.

还:

是的,函数是对象。
this在我的Point2D示例内部并没有指向 Point2D 函数......

它指向一个全新的对象,该对象被制作并返回。

如果您忘记使用new,猜猜什么会被用作this,而不是?
window做。

没有什么真正的神奇之处。

当您使用像我的 Point2D 构造函数这样的函数时,该函数会检查是否new被调用。如果是这样,那么this = {};就是在函数开始时在幕后发生的事情。如果不是,那么this = window就是所谓的。

但是嵌套函数也是如此。被new使用了吗?然后嵌套函数对一个 100% 全新的对象进行操作。否则,它在window.

唯一的四种解决方法是:

function sayName () { console.log(this.name); }

var bob = { name : "Bob" };

1).call(new_this)

sayName.call(bob); // Bob

证明函数是对象——它们都有自己的属性/方法

2).apply(new_this)

sayName.apply(bob);  // Bob

.apply并且.call除了参数如何传递给函数之外是相同的。

如果我.call在 Point2D 上使用,它看起来像:

var obj = {},
    x = 1,
    y = 3;

Point2D.call(obj, x, y);

现在,Point2D 不再创建新对象,而是在obj.
如果我要使用.apply它看起来像:

var obj = {},
    x = 1,
    y = 3;

Point2D.apply(obj, [x,y]);

全部区别在于您传递一个数组,而不是一次传递一个(对于您不知道有多少参数的情况)

...继续

3).bind像其他两个一样工作,除了不是触发函数,它制作函数的副本,其中this 总是指向同一个对象,而不是每次调用函数时都计算。

var sayBob = sayName.bind(bob);
sayBob(); // Bob

Bind 的工作原理是这样的:

function bind_this (new_this) {
    var func = this;
    return function () {
        func.call(new_this);
    }
}

function sayName () {
    console.log(this.name);
}

sayName.bind_this = bind_this;

var sayBob = sayName.bind_this(bob);
sayBob(); // Bob

为了让论点正确,还有更多的事情要做,但这就是想法。

4)只需将您想要使用的功能设置为您想要使用它的事物的属性......

var bob = { name : "Bob" };

function sayName () { console.log(this.name); }

bob.sayName = sayName;
bob.sayName(); // Bob

你有它......这些是使用方法this

如果使用newthen 则this指向一个新对象。
如果您使用.call .apply .bind或设置函数作为对象的属性,则this指向您设置的对象。

如果您不执行上述任何一项操作,请this指向window
函数是嵌套 6 深还是在全局范围内都没有关系。这些是你的选择。

想象一下我的 Point2D 看起来像这样:

var Point2D = function (x, y) {
    var this = undefined;
    if (new) { this = {}; }
    else if (called) { this = called; }
    else { this = window; }

    this.x = x;
    this.y = y;


    this.setX = function (x) {
        this = undefined;
        if (new) { this = {}; }
        else if (called) { this = called; }
        else { this = window; }
        /* this function is set as a property of another object -- so it is "called", always */
        this.x = x;
        if (new) { return this; }
    };

    this.setY = function (y) { /* same as setX */ };

    if (new) { return this; }
};

所有函数的内部,嵌套或非嵌套的工作,在引擎盖下......

所以现在,看着它,你应该看到它们之间的区别:

var obj = {};

var point = new Point2D(1, 3); // new object

var point2 = Point2D(2, 3); // point2 is empty and window gets the values

Point2D.call(obj, 5, 7); // obj is added to, instead of making a new object

所以现在,希望您了解以下内容:

var bob = {
    name : "bob",
    speak : function () {
        var name = this.name; // bob
        console.log(name + " is lower case.");

        function uppercase () {
            var window_name = this.name;
            console.log(window_name + " is window.name.");
        }
        uppercase();

        function working_uppercase () { console.log(this.name.toUpperCase()); }

        working_uppercase.call(this);
    }
};

如果你不明白为什么这是真的,那就相信我的话,相信我是对的,几年后,这将成为你的第二天性。

另一种解决方案可能是避免this或谨慎使用它以避免混淆。

var Point2D = function (x, y) {
    this.x = x;
    this.y = y;

    this.findMagnitude = function () {
        return Math.sqrt(this.x * this.x
                       + this.y * this.y);
    };
};

var point = Point2D(3, 7);

哎呀!没有new

point; // undefined
window.findMagnitude; // function () { ... }

那么为什么不处理不会搞砸的功能呢?

var Point2D = function (x, y) {
    var point = {
        x : x,
        y : y,
        setX : function (x) { this.x = x; },
        setY : function (y) { point.y = y; }
    };

    return point;
};


var point1 = Point2D(1, 3),
    point2 = Point2D(2, 7);

我什this至在其中一种方法上使用过,但是因为我是直接在对象上设置的,所以只要不将函数复制到其他地方或在回调中使用它就可以了。

另一个,我在...上使用了一个引用。该函数可以提供给其他对象,也可以作为返回值传递,或者异步调用,每次,它都会对完全相同的对象执行完全相同的操作,因为它引用了对象,而不是this.

于 2013-01-06T09:51:41.713 回答