顺序函数调用的执行上下文 - 这会更改为窗口

时间:2014-04-16 00:40:19

标签: javascript

我很遗憾地提出这样一个基本问题,但是尽管在过去的几个月里对javascript有很多阅读,特别是在这个问题上,我还没有得到关于它的执行情况和"这个"。因此,我希望使用我的具体方案进行解释会有所帮助。我有一个构造函数,其中我有一些本地函数和一些公开函数(模仿公共/私有方法)。

function blog() {
    if (!(this instanceof blog))
        return new blog();

    function internal(){
        alert(this);
    }

    this.external = function(){
        alert(this);
        internal();
    }
}

var b = new blog();
b.external();

external,"这个"是b,我期待的博客实例。我错误地期望它在internal内也是如此,但它实际上是全局窗口对象。作为一项实验,我尝试将external的调用更改为this.internal(),这会导致this.internal不是函数的错误。这是我意识到我真的没有关注它是如何工作的。好吧,我还没有定义一个名为internal的博客的属性,但如果内部不是我的博客实例上定义的函数,它是什么,它在哪里定义?也许我有这种结构错误。

2 个答案:

答案 0 :(得分:0)

请在此处查看xdazzs答案:https://stackoverflow.com/a/12241726/2469255

但是,要解决您的问题,您需要定义this对该函数的作用。

调用内部调用而不提供此上下文,因此它绑定到全局对象,不像this.external将其作用域限定为博客对象。按如下方式重写代码将解决这个问题:

function blog() {
    if (!(this instanceof blog))
        return new blog();

    function internal(){
        console.log(this);
    }

    this.external = function(){
       console.log(this);
       internal.bind(this);
       internal.call(this); // this in internal will be the object blog.
    }
}

var b = new blog();
b.external(); //blog {external: function} blog {external: function}

或者很多人更喜欢var self = this来确保这样的问题不会发生,而且您确切地知道要设置的是什么,在哪里。 YMMV

对这个特定的想法存在很多争论

答案 1 :(得分:0)

让我试着解释一下。

如果您在没有blog()关键字的情况下简单地致电new,则只能访问此段代码。

if (!(this instanceof blog))
    return new blog();

但是,这不是推荐的实践,因为它会影响您的代码。

因为:

var realObj = new Blog();

是实例化Object的正确代码,代码如下:

var obj = blog();

不够明确,可能会引导你犯错误。

JavaScript最初是原型继承,你可以从Douglas Crockford获得更好的解释here

internal()没有来自external的相同引用的主要原因是因为internal有一个指向全局的范围,当你创建一个blog实例时,外部范围指向对象博客

真的很混淆,因为博客声明中的this指向全局,那么为什么当您实例化博客this时会发生变化?

当浏览器开始读取您的代码时,它会将它在内存中找到的内容放在范围内引用。请记住范围由{}控制,因此当他发现您的声明this.external时,他与范围相关联,并且当您声明使用new this成为对象的范围时this {1}}不再提及全球范围。

在jsbin.com上查看此code