3

我正在尝试学习一些关于 javascript 的新概念。这是我编写的一个简单代码。在函数内部,这个关键字指的是全局对象,它是窗口,除非它与另一个对象的上下文绑定。在myobj对象内部有两个方法,它们分别与另外两个全局可访问的函数共享相同的名称afuncanotherfunc。我想在 myobj 上下文中访问这些全局函数,当然不使用将全局对象绑定到我曾经调用它们的立即调用的函数。但它抛出了一个错误。我的问题是,如果 javascript 中的所有内容都是一个对象,而 window 对象包含它们,那么为什么我可以使用this.afucnor访问这些函数window.afunc

(function(){
var afunc=function (){
    document.write('this is world'+'</br>');
}
var anotherfunc=function (){
   document.write('this is another world');
}
   var myobj={
       afunc:function(){
	        document.write('afunc');
	   },
	   anotherfunc:function(){
	        document.write('anotherfunc');
	   },
	   context:function(){
	       (function(){
		       this.afunc();
			   this.anotherfunc();
		   })();
	   }
	 };
   myobj.context();
})();

4

3 回答 3

2

确实,在您的情况下,this将引用全局对象,并且this.afunc()等将访问全局变量afunc

但是,除非要显示更多代码,否则您没有全局变量afunc。您定义的变量

(function(){
var afunc=function (){
    document.write('this is world'+'</br>');
}
var anotherfunc=function (){
   document.write('this is another world');
}
//...
})();

是封闭函数(零件)的局部。(function(){ ... })();

如果你想让它们全局化,你可以将它们移到函数之外:

var afunc = function() {
    document.write('this is world' + '</br>');
};
var anotherfunc = function() {
    document.write('this is another world');
};
(function() {
    var myobj = {
        afunc: function() {
            document.write('afunc');
        },
        anotherfunc: function() {
            document.write('anotherfunc');
        },
        context: function() {
            (function() {
                this.afunc();
                this.anotherfunc();
            })();
        }
    };
    myobj.context();
})();


但是,请注意,在严格模式下thisundefined不是指全局对象。这样做是因为通常如果有人this在函数内部使用,他们不希望它引用全局对象。只看代码,并不总是很清楚您是要访问全局对象(通过this)还是其他对象(正如您所注意到的,您的意图有些混乱)。

这就是为什么,如果你想访问全局对象,你应该明确地这样做并通过window.

于 2014-10-14T13:46:02.707 回答
1

首先,我认为你有些事情有点困惑。

在 JavaScript 中,并非一切都是函数。相反,可以使用一些不同的原语(从 ES5 开始):

  1. 细绳
  2. 数字
  3. 布尔值,
  4. 无效的
  5. 不明确的
  6. 目的

推荐阅读:关于 JavaScript 数据结构的 Mozilla 文档

这些类型中的每一种都有与之相关的特殊方法——除了nulland undefined,它们是具有非常特定用途的占位符——但这些对于帮助你理解 JavaScript 中发生的事情并不重要。帮助的关键之一是 JavaScript 是所谓的函数式语言的想法。在某种程度上,这意味着函数是一流的对象。除此之外,这意味着可以将函数用作值。

另一件事是,返回的函数并不是唯一返回的东西——函数编程是围绕闭包的思想构建的,或者是函数以及定义返回函数的范围内的所有相关变量(毕竟,我们可以在返回新函数的函数中引用变量!)

function foo() {
    var bar = 3;

    // Returns a function that when called, returns the Number 5.
    return function () {
        return 1 + 1 + bar;
    }
}

就缩小错误范围而言,在您的myObj.context函数中,我注意到您已经编写了一个立即调用的表达式...

context: function () {
    (function () {
        this.afunc();
        this.anotherfunc();
    })();
},

这真的有必要吗?事实上,这个功能真的有必要吗?由于我们现在知道 JavaScript 将对象上的函数视为值,因此您始终可以只执行myObj.afuncmyObj.anotherfunc使用特定于myObj.

如果您的意图是编写一个可以调用afuncanotherfunc方法的方法myObj,那么一组更好的代码将是:

var myObj = {
    afunc: function () {
        // Magic!
    },
    anotherfunc: function () {
        // More magic!
    },
    context: function () {
        this.afunc();
        this.anotherfunc();
    }
};

如果您的意图是调用围绕声明的立即调用表达式中定义的afunc/ ,只需从调用中删除。anotherfuncmyObjthiscontext

如果您的意图是在全局范围内调用afunc/anotherfunc方法,那么您很不走运:您没有在给定的代码段中定义此类函数。但是,这可以像这样修复:

// Now, afunc exists in the global scope!
function afunc() {
    // Magic
}

// Now, anotherfunc exists in the global scope!
function anotherfunc() {
    // Magic
}

(function () {
    var myObj = {
        // Your object...
    };

    myObj.context();
})();

不过,一般来说,这被认为是糟糕的编程形式,因为我们用不必要的函数、变量和对象来弄乱全局范围;最好将函数声明保留在立即调用对象中,除非您需要在其他地方调用它们。如果您需要在其他地方调用这些函数,您可能会考虑研究如何执行此操作。

于 2014-10-14T13:44:40.040 回答
0

它不起作用,因为this不是指您认为它指的是什么,而是坚持使用window. 从那里开始,外部的函数并不完全在全局范围内,因为它们被包裹在(function(){ ... })();. 现在对于您的context函数,我们不需要function()包装器,因为全局范围内没有任何内容:

   context:function(){
       (function(){ // <-- Here
           this.afunc();
           this.anotherfunc();
       })(); //        <--
   }

删除它(无论如何我们都不想要它)this并将引用一个实例myobj

   context:function(){
       this.afunc();
       this.anotherfunc();
   }

如果我们想获得在myobj范围之外声明的那些,那么你不想使用this. 因为这意味着属于 的实例的函数myobj。你只想说:

   context:function(){
       afunc();
       anotherfunc();
   }

因为myobj不了解“全局”功能。

(function(){
var afunc=function (){
    document.write('this is world'+'</br>');
}
var anotherfunc=function (){
   document.write('this is another world');
}
   var myobj={
       afunc:function(){
	        document.write('afunc');
	   },
	   anotherfunc:function(){
	        document.write('anotherfunc');
	   },
	   context:function(){
               afunc();
               anotherfunc();
	   }
	 };
   myobj.context();
})();

于 2014-10-14T13:33:25.870 回答