What underlies this JavaScript idiom: var self = this?

前端 未结 10 1899
长情又很酷
长情又很酷 2020-11-22 03:37

I saw the following in the source for WebKit HTML 5 SQL Storage Notes Demo:

function Note() {
  var self = this;

  var note = document.createElement(\'d         


        
相关标签:
10条回答
  • 2020-11-22 04:14

    I think the variable name 'self' should not be used this way anymore, since modern browsers provide a global variable self pointing to the global object of either a normal window or a WebWorker.

    To avoid confusion and potential conflicts, you can write var thiz = this or var that = this instead.

    0 讨论(0)
  • As mentioned several times above, 'self' is simply being used to keep a reference to 'this' prior to entering the funcition. Once in the function 'this' refers to something else.

    0 讨论(0)
  • 2020-11-22 04:20

    See this article on alistapart.com. (Ed: The article has been updated since originally linked)

    self is being used to maintain a reference to the original this even as the context is changing. It's a technique often used in event handlers (especially in closures).

    Edit: Note that using self is now discouraged as window.self exists and has the potential to cause errors if you are not careful.

    What you call the variable doesn't particularly matter. var that = this; is fine, but there's nothing magic about the name.

    Functions declared inside a context (e.g. callbacks, closures) will have access to the variables/function declared in the same scope or above.

    For example, a simple event callback:

    function MyConstructor(options) {
      let that = this;
    
      this.someprop = options.someprop || 'defaultprop';
    
      document.addEventListener('click', (event) => {
        alert(that.someprop);
      });
    }
    
    new MyConstructor({
      someprop: "Hello World"
    });

    0 讨论(0)
  • 2020-11-22 04:20

    As others have explained, var self = this; allows code in a closure to refer back to the parent scope.

    However, it's now 2018 and ES6 is widely supported by all major web browsers. The var self = this; idiom isn't quite as essential as it once was.

    It's now possible to avoid var self = this; through the use of arrow functions.

    In instances where we would have used var self = this:

    function test() {
        var self = this;
        this.hello = "world";
        document.getElementById("test_btn").addEventListener("click", function() {
            console.log(self.hello); // logs "world"
        });
    };
    

    We can now use an arrow function without var self = this:

    function test() {
        this.hello = "world";
        document.getElementById("test_btn").addEventListener("click", () => {
            console.log(this.hello); // logs "world"
        });
    };
    

    Arrow functions do not have their own this and simply assume the enclosing scope.

    0 讨论(0)
  • 2020-11-22 04:20

    It's a JavaScript quirk. When a function is a property of an object, more aptly called a method, this refers to the object. In the example of an event handler, the containing object is the element that triggered the event. When a standard function is invoked, this will refer to the global object. When you have nested functions as in your example, this does not relate to the context of the outer function at all. Inner functions do share scope with the containing function, so developers will use variations of var that = this in order to preserve the this they need in the inner function.

    0 讨论(0)
  • 2020-11-22 04:23

    It should also be noted there is an alternative Proxy pattern for maintaining a reference to the original this in a callback if you dislike the var self = this idiom.

    As a function can be called with a given context by using function.apply or function.call, you can write a wrapper that returns a function that calls your function with apply or call using the given context. See jQuery's proxy function for an implementation of this pattern. Here is an example of using it:

    var wrappedFunc = $.proxy(this.myFunc, this);

    wrappedFunc can then be called and will have your version of this as the context.

    0 讨论(0)
提交回复
热议问题