Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript &引用;这";指的是别的什么?_Javascript - Fatal编程技术网

Javascript &引用;这";指的是别的什么?

Javascript &引用;这";指的是别的什么?,javascript,Javascript,当我运行此代码时: var Test = function() { return this.stuff; }; Test.stuff = 'Neat!'; document.write(Test() || 'Not neat.'); 为什么我会“不整洁”?为什么我不能使用this.stuff访问stuff属性?您从全局上下文调用了Test,因此this引用全局对象,因此this.stuff引用全局变量stuff,它是未定义的,是错误的。这就是您看到不整洁的原因。 您可以使它显示整洁

当我运行此代码时:

var Test = function() {
    return this.stuff;
};

Test.stuff = 'Neat!';

document.write(Test() || 'Not neat.');

为什么我会“不整洁”?为什么我不能使用
this.stuff
访问stuff属性?

您从全局上下文调用了
Test
,因此
this
引用全局对象,因此
this.stuff
引用全局变量
stuff
,它是
未定义的
,是错误的。这就是您看到
不整洁的原因。

您可以使它显示
整洁如下所示:

附录

这里有一种方法可以让
这个
作为一个封闭对象工作:

这里我们通过一个目标对象调用
Test


类方法和变量位于prototype属性上:

Test.prototype.stuff = 'Neat!'
构造函数函数(我假设这是您想要的,考虑到大写字母和
this
)应该使用
new
操作符调用:

new Test()
它们不应该返回值(您应该使用默认值返回
this


至于您的实际需要,您可以直接访问函数及其属性

function Test(){
    return Test.stuff;
}
然而,我不是一个滥用名称空间函数的狂热者。我更喜欢使用名称空间对象来进行操作

//in a real case I would probably use the module pattern for private variables
//but whatever...

var Namespace = {};

Namespace.stuff = 'Neat!';

Namespace.F = function(){
    console.log(Namespace.stuff);
};

stuff属性已分配给函数,但从全局。。。这两个是独立的实体

这就是您所做的:

var Test = function() {                //Test is a Function object
    return this.stuff;                 //this is a pointer to an object, not Test
};

Test.stuff = 'Neat!';                  //Add a property to Test

document.write(Test() || 'Not neat.'); //this has no property stuff
将代码的最后一行更改为:

document.write(Test.call(Test) || 'Not neat.'); //this now points to Test
代码不起作用的原因是
this
指针指向:

  • 当函数调用以
    new
    关键字作为前缀时创建的构造函数实例。(例如,
    var foo=new foo();//this in foo指向foo[为了解释]
  • 传递给
    调用
    应用
    的对象用作第一个参数
  • 您想做的是:

    var Test = function Temp() {           //Test is a Function object, alias Temp
        return Temp.stuff;                 //Temp is the same as Test, only locally
    };
    
    Test.stuff = 'Neat!';                  //Add a property to Test
    
    document.write(Test() || 'Not neat.'); //writes Neat!
    

    如果你喜欢这个答案,就投票吧。干杯。

    虽然其他人已经发布了发生这种情况的原因(对
    这个
    的理解是不正确的),但这里有一个解决方案可以可靠地工作

    更新:正如Raynos所指出的,在ECMAScript第5版中,使用
    参数是无效的。被调用方
    (它将抛出一个类型错误)。因此,如果使用这种方法,应谨慎行事。(使用[correct]ECMAScript第5版引擎时,没有理由在绑定到新作用域的函数的名称上使用
    参数。被调用方
    ——请参见答案的结尾。)

    另一种方法是使用闭包:

    var Test = (function () {
      function fn () {
        // closure over fn, which names this function-object
        return fn.stuff
      }
      fn.stuff = 'Neat!' // here
      return fn          // do not combine with function declaration!
    })()
    Test.stuff = 'Neat!' // or here
    alert(Test() || 'Not neat.') // Neat!
    
    或者,直接对变量进行闭包:

    var Test = (function () {
      var stuff = 'Neat!'
      return function () {
        // variable closure, no property
        return stuff
      }
    })()
    alert(Test() || 'Not neat.') // Neat!
    
    或者。。。很多方面

    快乐编码


    Aadit M Shah指出的另一种方法是使用函数标识符引用当前函数:

    var Test = function Temp () {
       return Temp.stuff
    }
    Test.stuff = 'Neat!'
    alert(Test() || 'Not neat.') // Neat! (But see below.)
    
    正如Aadit所指出的,根据第99页:

    FunctionExpression中的标识符可以从FunctionExpression的FunctionBody内部引用到 允许函数递归地调用自身。但是,与FunctionDeclaration不同,FunctionExpression中的标识符不能从中引用,也不会影响包含FunctionExpression的范围

    然而,一些浏览器(至少IE9)没有正确地实现这一点(我不确定上述行为是否在第三版中定义良好)。考虑:

    var x = function y () { return y }; y = 42; x();
    
    在IE9中,它将产生42,在FF8中,它将产生函数对象。IE9在这里是不正确的,因为它在封闭范围中引入了
    y
    ,这是ECMAScript禁止用于函数表达式的变量。下面是一个上下文示例,说明了这种错误的实现如何导致不同的结果:

    var Test = function Temp () {
       return Temp.stuff
    }
    Test.stuff = "Neat!"
    Temp = {}
    alert(Test() || 'Not neat.') // 'Not neat.' in IE9, 'Neat!' in FF8
    

    你到底想在这里做什么?我实际上想使用类似jQuery对象的类(不实例化):
    Test('do something');Test.default=500;Test(‘用500做点什么’)
    @AlicanC这里有一篇由johnresig写的关于这个话题的帖子@皮特:那篇文章很好,但是是2007年的。我现在在jQuery1.7的源代码中找不到
    arguments.calee的任何用法。也许他们采用了一种新的方法?我似乎不明白。@AlicanC-据我所知,您真正想要的是一种类似于我在回答中描述的模式(即
    var Test=function Temp(){return Temp.stuff;};
    )。它很快,也很优雅。另外,即使人们以后更改代码,比如
    Test=5,它不会打断您的代码,因为函数的内部名称(即
    Temp
    )仍然指向函数本身。它不能从外部修改。希望这有帮助。干杯。使用arguments.callee和直接重复函数名有什么区别?@missingno Preference:)我已经使用了这两种方法,这取决于我想做什么,以及“它”与其余代码的匹配程度。我想不出一个“普遍的”优势或劣势,但如果我忽略了什么,我也不会感到惊讶。只是小心不要“太聪明”。。。请注意,在全局上下文中,is与
    var Test=function(){return Test.stuff}
    不同,因为
    Test
    实际上可能是
    window.Test
    ,一个属性,而不是封闭变量。有人以后可能会用
    Test=function(){}
    破坏一些东西。。。永远不知道:)我不喜欢使用
    参数。被调用方
    。我也不喜欢使用
    var Test=function(){return Test.stuff;}。两者都是访问数据的缓慢方法。这是因为
    被调用方
    参数
    的一种方法,而解释器会花费更多的时间来访问它。类似地,
    Test
    在本地范围内不存在。因此,解释器必须向上移动才能在父作用域中找到它。相反,我更喜欢以下方法:
    var Test=function Temp(){return Temp.stuff;}。这里的
    Temp
    是一个al
    var Test = (function () {
      var stuff = 'Neat!'
      return function () {
        // variable closure, no property
        return stuff
      }
    })()
    alert(Test() || 'Not neat.') // Neat!
    
    var Test = function Temp () {
       return Temp.stuff
    }
    Test.stuff = 'Neat!'
    alert(Test() || 'Not neat.') // Neat! (But see below.)
    
    var x = function y () { return y }; y = 42; x();
    
    var Test = function Temp () {
       return Temp.stuff
    }
    Test.stuff = "Neat!"
    Temp = {}
    alert(Test() || 'Not neat.') // 'Not neat.' in IE9, 'Neat!' in FF8