javascript:核心执行概念

时间:2013-01-06 08:46:40

标签: javascript

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

现在,根据此关键字的定义“这指向函数运行的当前对象”

由于上述函数对新创建的对象进行操作,因此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对象。

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

我知道我正在明确地调用这个函数但是根据上面的定义我的观点是否正确?

2 个答案:

答案 0 :(得分:1)

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

  1. 您只是调用外部函数,而不是实例化它
  2. 警告值是内部函数的上下文,默认情况下是窗口。如果您使用foo作为构造函数,外部函数的上下文将是实例。
  3. 详细说明第二点,如果您要运行以下代码,则记录的值将是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();
    

答案 1 :(得分: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,请猜猜用作{{​​1}}的是什么? this确实如此。

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

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

但嵌套函数也是如此。 是this = window使用过吗?然后嵌套函数在100%全新的对象上运行。否则,它会在new上运行。

解决这个问题的唯一方法是:

window

1)function sayName () { console.log(this.name); } var bob = { name : "Bob" };

.call(new_this)

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

2)sayName.call(bob); // Bob

.apply(new_this)
除了参数如何传递给函数之外,

sayName.apply(bob); // Bob .apply是相同的。

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

.call

现在,Point2D不会创建新对象,而是在var obj = {}, x = 1, y = 3; Point2D.call(obj, x, y); 上完成所有工作 如果我要使用obj,它看起来像是:

.apply

完全不同的是你传递一个数组,而不是一次传递一个数组(对于你不知道有多少个参数的情况)

......继续前进

3)var obj = {}, x = 1, y = 3; Point2D.apply(obj, [x,y]); 与其他两个一样工作,除了触发该函数之外,它还复制了该函数,其中.bind 总是 指向同一个对象,而不是每次调用函数时计算。

this

Bind的作品有点像这样:

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

还有一点,要争辩,但这就是主意。

4)只需设置您想要用作想要使用它的东西的属性......

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

你有它...... 这些是使用var bob = { name : "Bob" }; function sayName () { console.log(this.name); } bob.sayName = sayName; bob.sayName(); // Bob

的方法

如果您使用this,则new指向新对象 如果您使用this .call .apply或将该函数设置为对象的属性,则.bind指向您设置的对象。

如果您没有执行上述任何一项操作,this指向this 函数是否嵌套6深,或者它是否在全局范围内并不重要。这些是你的选择。

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

window

所有功能的内部,嵌套或非嵌套的工作,在幕后......

所以现在,看一下,你应该看到它们之间的差异:

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