this keyword is window object within a constructor function

前提是你 提交于 2020-01-24 03:10:28

问题


Ok, so I thought I understood this (no pun intended), but apparently not.

var Constructor = function () {
    var internalFunction = function () {
        return this === window;
    };
    this.myMethod = function () {
        alert(internalFunction());
    };
};
var myObj = new Constructor();
myObj.myMethod();

This alerts true. Why can't the internal function see this as the object? Instead I have to use alert(internalFunction.call(this)); in myMethod.

Edit: I was looking for an explanation as to why this is assigned in that way, not workarounds such as var self = this;, etc. Sorry if I didn't make that clear.


回答1:


this is not bound until the function is called and is dependent on how the function is called. You could think of it as an extra parameter implicitly passed to the function.

In this case, the problem is that you're calling internalFunction using internalFunction(). The this value is set either by calling a function as a method (as in foo.bar() or foo["bar"]()) or by setting this explictly via call() or apply(). Your call is doing neither so this reverts to the global object.

The simplest way to achieve what you want in this case while keeping internalFunction private is to store a reference to this inside the constructor function:

var Constructor = function() {
    var thisObj = this;

    var internalFunction = function () {
        return thisObj === window;
    };

    thisObj.myMethod = function () {
        alert(internalFunction());
    };
}



回答2:


Because of functional scoping rules, this is reassigned inside each function... I would store a copy of your object as self and use it accordingly...

var Constructor = function () {

    var self = this;

    var internalFunction = function () {
        return self === window;
    };
    this.myMethod = function () {
        alert(internalFunction());
    };
};
var myObj = new Constructor();
myObj.myMethod();

Should give you the output you expect.

SIDENOTE

This is a fairly precarious practice that javascript has created, mainly because if you forget the new keyword when using Constructor, you will get this referring to the window (god) object so you'll be attaching myMethod to the window without warning.




回答3:


There are five ways to call a function in JavaScript. The value of this depends on which you choose:

  1. Global function call (e.g. myFunction()). No explicit value for this is given. The value of this will be the default object (window in a browser).
  2. Method call (e.g. obj.myFunction()). The value of this is the object on which the method was invoked (obj in this case).
  3. Using the call method (e.g. myFunction.call(obj)). The value of this is provided explicitly (in this case obj).
  4. Using the apply method (e.g. myFunction.apply(obj)). The value of this is provided explicitly (in this case obj).
  5. Constructor function (e.g. new MyFunction()). The value of this is a newly-created object provided by the runtime.

Each of the five is explained in more detail here:

  • http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx



回答4:


Its a scope issue try something like:

var Constructor = function () {
    var $this = this;
    var internalFunction = function () {
        return $this === window;
    };
    this.myMethod = function () {
        alert(internalFunction());
    };
};
var myObj = new Constructor();
myObj.myMethod();


来源:https://stackoverflow.com/questions/7982084/this-keyword-is-window-object-within-a-constructor-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!