This translation is incomplete. Please help translate this article from English.
ה"קי-וורד" this מתנהג טיפה שונה בjs בהשוואה לשפות אחרות. יש לציין כי קיים הבדל בין strict mode ו- non-strict mode.
ברוב המקרים, הערך של this נקבע לפי הקריאה לפונקציה. לא ניתן לבצע השמה תוך הרצה, והערך עלול להיות שונה בכל קריאה לפונקציה. בES5 הוצג לראשונה bind לקביעת ערך לthis בפונקציה ללא קשר לקריאה, ובES2015 הוצג arrow functions.
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
Syntax
this
Global Context
In the global execution context (outside of any function), this refers to the global object whether in strict mode or not.
console.log(this === window); // true a = 37;
console.log(window.a); // 37 this.b = "MDN";
Function context
Inside a function, the value of this depends on how the function is called.
Simple call
Since the following code is not in strict mode, and because the value of this is not set by the call, this will default to the global object, which is window in a browser.
return this;
}
// In Node:
In strict mode, however, the value of this remains at whatever it was set to when entering the execution context, so, in the following case, this will default to undefined:
return this; }
So, in strict mode, if this was not defined by the execution context, it remains undefined.
this should be undefined, because f2 was called directly and not as a method or property of an object (e.g. window.f2()). This feature wasn't implemented in some browsers when they first started to support strict mode. As a result, they incorrectly returned the window object.To pass the value of this from one context to another, use call, or apply:
var obj = {a: 'Custom'}; // This property is set on the global object var a = 'Global';
function whatsThis(arg) { } whatsThis(); // 'Global' whatsThis.call(obj); // 'Custom'
Where a function uses the this keyword in its body, its value can be bound to a particular object in the call using the call or apply methods which all functions inherit from Function.prototype.
} var o = {a: 1, b: 3};
// 'this', subsequent parameters are passed as
// arguments in the function call add.call(o, 5, 7); // 16
// 'this', the second is an array whose
Note that with call and apply, if the value passed as this is not an object, an attempt will be made to convert it to an object using the internal ToObject operation. So if the value passed is a primitive like 7 or 'foo', it will be converted to an Object using the related constructor, so the primitive number 7 is converted to an object as if by new Number(7) and the string 'foo' to an object as if by new String('foo'), e.g.
} bar.call(7); // [object Number]
The bind method
ECMAScript 5 introduced Function.prototype.bind. Calling f.bind(someObject) creates a new function with the same body and scope as f, but where this occurs in the original function, in the new function it is permanently bound to the first argument of bind, regardless of how the function is being used.
}
console.log(g()); // azerty
console.log(h()); // azerty var o = {a: 37, f: f, g: g, h: h};
Arrow functions
In arrow functions, this retains the value of the enclosing lexical context's this. In global code, it will be set to the global object:
var foo = (() => this);
Note: if this arg is passed to call, bind, or apply on invocation of an arrow function it will be ignored. You can still prepend arguments to the call, but the first argument (thisArg) should be set to null.
var obj = {func: foo};
// Attempt to set this using call
console.log(foo.call(obj) === globalObject); // true foo = foo.bind(obj);
No matter what, foo's this is set to what it was when it was created (in the example above, the global object). The same applies to arrow functions created inside other functions: their this remains that of the enclosing lexical context.
// returns its this. The returned function is created as
// this of its enclosing function. The value of bar can be set // in the call, which in turn sets the value of the
// returned function. var obj = {bar: function() { var x = (() => this); } };
// Call bar as a method of obj, setting its this to obj // Assign a reference to the returned function to fn var fn = obj.bar(); // to the global object or undefined in strict mode
console.log(fn() === obj); // true // But caution if you reference the method of obj without calling it var fn2 = obj.bar;
In the above, the function(call it anonymous function A) assigned to obj.bar returns another function(call it anonymous function B) that is created as an arrow function. As a result, function B's this is permanently set to the this of obj.bar (function A)when called. When the returned function(function B) is called, its this will always be what it was set to initially. In the above code example, function B's this is set to function A's this which is obj, so it remains set to obj even when called in a manner that would normally set its this to undefined or the global object (or any other method as in the previous example in the global execution context).
As an object method
When a function is called as a method of an object, its this is set to the object the method is called on.
In the following example, when o.f() is invoked, inside the function this is bound to the o object.
} };
Note that this behavior is not at all affected by how or where the function was defined. In the previous example, we defined the function inline as the f member during the definition of o. However, we could have just as easily defined the function first and later attached it to o.f. Doing so results in the same behavior:
return this.prop; }
o.f = independent;
This demonstrates that it matters only that the function was invoked from the f member of o.
Similarly, the this binding is only affected by the most immediate member reference. In the following example, when we invoke the function, we call it as a method g of the object o.b. This time during execution, this inside the function will refer to o.b. The fact that the object is itself a member of o has no consequence; the most immediate reference is all that matters.
this on the object's prototype chain
The same notion holds true for methods defined somewhere on the object's prototype chain. If the method is on an object's prototype chain, this refers to the object the method was called on, as if the method were on the object.
var p = Object.create(o); p.a = 1; p.b = 4;
In this example, the object assigned to the variable p doesn't have its own f property, it inherits it from its prototype. But it doesn't matter that the lookup for f eventually finds a member with that name on o; the lookup began as a reference to p.f, so this inside the function takes the value of the object referred to as p. That is, since f is called as a method of p, its this refers to p. This is an interesting feature of JavaScript's prototype inheritance.
this with a getter or setter
Again, the same notion holds true when a function is invoked from a getter or a setter. A function used as getter or setter has its this bound to the object from which the property is being set or gotten.
} var o = { a: 1, b: 2,
c: 3, get average() { } };
Object.defineProperty(o, 'sum', {
As a constructor
When a function is used as a constructor (with the new keyword), its this is bound to the new object being constructed.
While the default for a constructor is to return the object referenced by this, it can instead return some other object (if the return value isn't an object, then the this object is returned).
* * function MyConstructor(){
* // Create properties on |this| as
* // desired by assigning to them. E.g., * this.fum = "nom"; *
* // If the function has a return statement that * // result of the |new| expression. Otherwise,
* // the result of the expression is the object * // currently bound to |this| * } */ function C() { this.a = 37; } var o = new C();
console.log(o.a); // 37 function C2() { this.a = 37; return {a: 38}; }
In the last example (C2), because an object was returned during construction, the new object that this was bound to simply gets discarded. (This essentially makes the statement "this.a = 37;" dead code. It's not exactly dead because it gets executed, but it can be eliminated with no outside effects.)
As a DOM event handler
When a function is used as an event handler, its this is set to the element the event fired from (some browsers do not follow this convention for listeners added dynamically with methods other than addEventListener).
function bluify(e) { // Always true
console.log(this === e.currentTarget); console.log(this === e.target);
this.style.backgroundColor = '#A5D9F3'; } var elements = document.getElementsByTagName('*');
// Add bluify as a click listener so when the // element is clicked on, it turns blue elements[i].addEventListener('click', bluify, false);
In an inline event handler
When the code is called from an inline on-event handler, its this is set to the DOM element on which the listener is placed:
Show this
The above alert shows button. Note however that only the outer code has its this set this way:
Show inner this
In this case, the inner function's this isn't set so it returns the global/window object (i.e. the default object in non–strict mode where this isn't set by the call).
Specifications
| Specification | Status | Comment |
|---|---|---|
| ECMAScript Latest Draft (ECMA-262) The definition of 'The this keyword' in that specification. |
Draft | |
| ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'The this keyword' in that specification. |
Standard | |
| ECMAScript 5.1 (ECMA-262) The definition of 'The this keyword' in that specification. |
Standard | |
| ECMAScript 3rd Edition (ECMA-262) The definition of 'The this keyword' in that specification. |
Standard | |
| ECMAScript 1st Edition (ECMA-262) The definition of 'The this keyword' in that specification. |
Standard | Initial definition. Implemented in JavaScript 1.0. |
Browser compatibility
| Desktop | Mobile | Server | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
this | Chrome Full support Yes | Edge Full support Yes | Firefox Full support 1 | IE Full support Yes | Opera Full support Yes | Safari Full support Yes | WebView Android Full support Yes | Chrome Android Full support Yes | Firefox Android Full support 4 | Opera Android Full support Yes | Safari iOS Full support Yes | Samsung Internet Android Full support Yes | nodejs Full support Yes |
Legend
- Full support
- Full support