diff options
Diffstat (limited to 'files/pl/web/javascript/referencje/operatory/this/index.html')
-rw-r--r-- | files/pl/web/javascript/referencje/operatory/this/index.html | 346 |
1 files changed, 346 insertions, 0 deletions
diff --git a/files/pl/web/javascript/referencje/operatory/this/index.html b/files/pl/web/javascript/referencje/operatory/this/index.html new file mode 100644 index 0000000000..523e210cb6 --- /dev/null +++ b/files/pl/web/javascript/referencje/operatory/this/index.html @@ -0,0 +1,346 @@ +--- +title: this +slug: Web/JavaScript/Referencje/Operatory/this +translation_of: Web/JavaScript/Reference/Operators/this +--- +<div> +<div>{{jsSidebar("Operators")}}</div> +</div> + +<h2 id="Summary">Summary</h2> + +<p>W JavaScript słówko kluczowe <code>this</code> zachowuje się nieco inaczej w porównaniu do innych języków programowania. Istnieje również kilka różnic między trybem <a href="/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode">strict mode</a> oraz non-strict mode.</p> + +<p>W większości przypadków wartość <code>this</code> jest ustalana na podstawie tego, jak wywołana została dana funkcja. Wartość ta nie może być przypisana podczas wykonywania się funkcji i może być inna za każdym wywołaniem. ES5 wprowadziło metodę <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">bind</a></code> dzięki której <a href="#The_bind_method">możemy przypisać wartość <code>this</code> w funkcji, niezależnie od tego jak została ona wywołana.</a></p> + +<h2 id="Syntax">Syntax</h2> + +<pre class="syntaxbox">this</pre> + +<h2 id="Global_context">Global context</h2> + +<p>In the global execution context (outside of any function), <code>this</code> refers to the global object, whether in strict mode or not.</p> + +<pre class="brush:js">console.log(this.document === document); // true + +// In web browsers, the window object is also the global object: +console.log(this === window); // true + +this.a = 37; +console.log(window.a); // 37 +</pre> + +<h2 id="Function_context">Function context</h2> + +<p>Inside a function, the value of <code>this</code> depends on how the function is called.</p> + +<h3 id="Simple_call">Simple call</h3> + +<pre class="brush:js">function f1(){ + return this; +} + +f1() === window; // global object +</pre> + +<p>In this case, the value of <code>this</code> is not set by the call. Since the code is not in strict mode, the value of <code>this</code> must always be an object so it defaults to the global object.</p> + +<pre class="brush:js">function f2(){ + "use strict"; // see strict mode + return this; +} + +f2() === undefined; +</pre> + +<p>In strict mode, the value of <code>this</code> remains at whatever it's set to when entering the execution context. If it's not defined, it remains undefined. It can also be set to any value, such as <code>null</code> or <code>42</code> or <code>"I am not this"</code>.</p> + +<div class="note"><strong>Note:</strong> In the second example, <code>this</code> should be <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined"><code>undefined</code></a>, because <code>f2</code> was called without providing any base (e.g. <code>window.f2()</code>). This feature wasn't implemented in some browsers when they first started to support <a href="/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode" title="Strict mode">strict mode</a>. As a result, they incorrectly returned the <code>window</code> object.</div> + +<h3 id="As_an_object_method">As an object method</h3> + +<p>When a function is called as a method of an object, its <code>this</code> is set to the object the method is called on.</p> + +<p>In the following example, when <code>o.f()</code> is invoked, inside the function <code>this</code> is bound to the <code>o</code> object.</p> + +<pre class="brush:js">var o = { + prop: 37, + f: function() { + return this.prop; + } +}; + +console.log(o.f()); // logs 37 +</pre> + +<p>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 <code>f</code> member during the definition of <code>o</code>. However, we could have just as easily defined the function first and later attached it to <code>o.f</code>. Doing so results in the same behavior:</p> + +<pre class="brush:js">var o = {prop: 37}; + +function independent() { + return this.prop; +} + +o.f = independent; + +console.log(o.f()); // logs 37 +</pre> + +<p>This demonstrates that it matters only that the function was invoked from the <code>f</code> member of <code>o</code>.</p> + +<p>Similarly, the <code>this</code> 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 <code>g</code> of the object <code>o.b</code>. This time during execution, <code>this</code> inside the function will refer to <code>o.b</code>. The fact that the object is itself a member of <code>o</code> has no consequence; the most immediate reference is all that matters.</p> + +<pre class="brush:js">o.b = {g: independent, prop: 42}; +console.log(o.b.g()); // logs 42 +</pre> + +<h4 id="this_on_the_objects_prototype_chain"><code>this</code> on the object's prototype chain</h4> + +<p>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, <code>this</code> refers to the object the method was called on, as if the method was on the object.</p> + +<pre class="brush:js">var o = {f:function(){ return this.a + this.b; }}; +var p = Object.create(o); +p.a = 1; +p.b = 4; + +console.log(p.f()); // 5 +</pre> + +<p>In this example, the object assigned to the variable <code>p</code> doesn't have its own <code>f</code> property, it inherits it from its prototype. But it doesn't matter that the lookup for <code>f</code> eventually finds a member with that name on <code>o</code>; the lookup began as a reference to <code>p.f</code>, so <code>this</code> inside the function takes the value of the object referred to as <code>p</code>. That is, since <code>f</code> is called as a method of <code>p</code>, its <code>this</code> refers to <code>p</code>. This is an interesting feature of JavaScript's prototype inheritance.</p> + +<h4 id="this_with_a_getter_or_setter"><code>this</code> with a getter or setter</h4> + +<p>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 <code>this</code> bound to the object from which the property is being set or gotten.</p> + +<pre class="brush:js">function modulus(){ + return Math.sqrt(this.re * this.re + this.im * this.im); +} + +var o = { + re: 1, + im: -1, + get phase(){ + return Math.atan2(this.im, this.re); + } +}; + +Object.defineProperty(o, 'modulus', { + get: modulus, enumerable:true, configurable:true}); + +console.log(o.phase, o.modulus); // logs -0.78 1.4142 +</pre> + +<h3 id="As_a_constructor">As a constructor</h3> + +<p>When a function is used as a constructor (with the <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/new">new</a></code> keyword), its <code>this</code> is bound to new object being constructed.</p> + +<p>Note: while the default for a constructor is to return the object referenced by <code>this</code>, it can instead return some other object (if the return value isn't an object, then the <code>this</code> object is returned).</p> + +<pre class="brush:js">/* + * Constructors work like this: + * + * function MyConstructor(){ + * // Actual function body code goes here. + * // Create properties on |this| as + * // desired by assigning to them. E.g., + * this.fum = "nom"; + * // et cetera... + * + * // If the function has a return statement that + * // returns an object, that object will be the + * // result of the |new| expression. Otherwise, + * // the result of the expression is the object + * // currently bound to |this| + * // (i.e., the common case most usually seen). + * } + */ + +function C(){ + this.a = 37; +} + +var o = new C(); +console.log(o.a); // logs 37 + + +function C2(){ + this.a = 37; + return {a:38}; +} + +o = new C2(); +console.log(o.a); // logs 38 +</pre> + +<p>In the last example (<code>C2</code>), because an object was returned during construction, the new object that <code>this</code> was bound to simply gets discarded. (This essentially makes the statement "<code>this.a = 37;</code>" dead code. It's not exactly dead, because it gets executed, but it can be eliminated with no outside effects.)</p> + +<h3 id="call_and_apply"><code>call</code> and <code>apply</code></h3> + +<p>Where a function uses the <code>this</code> keyword in its body, its value can be bound to a particular object in the call using the <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call">call</a></code> or <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply">apply</a></code> methods that all functions inherit from <code>Function.prototype</code>.</p> + +<pre class="brush:js">function add(c, d){ + return this.a + this.b + c + d; +} + +var o = {a:1, b:3}; + +// The first parameter is the object to use as +// 'this', subsequent parameters are passed as +// arguments in the function call +add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16 + +// The first parameter is the object to use as +// 'this', the second is an array whose +// members are used as the arguments in the function call +add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34 +</pre> + +<p>Note that with <code>call</code> and <code>apply</code>, if the value passed as <code>this</code> is not an object, an attempt will be made to convert it to an object using the internal <code>ToObject</code> operation. So if the value passed is a primitive like <code>7</code> or <code>'foo'</code>, it will be converted to an Object using the related constructor, so the primitive number <code>7</code> is converted to an object as if by <code>new Number(7)</code> and the string <code>'foo'</code> to an object as if by <code>new String('foo'), e.g.</code></p> + +<pre class="brush:js">function bar() { + console.log(Object.prototype.toString.call(this)); +} + +bar.call(7); // [object Number] +</pre> + +<h3 id="The_bind_method">The <code>bind</code> method</h3> + +<p>ECMAScript 5 introduced <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">Function.prototype.bind</a></code>. Calling <code>f.bind(someObject)</code> creates a new function with the same body and scope as <code>f</code>, but where <code>this</code> occurs in the original function, in the new function it is permanently bound to the first argument of <code>bind</code>, regardless of how the function is being used.</p> + +<pre class="brush:js">function f(){ + return this.a; +} + +var g = f.bind({a:"azerty"}); +console.log(g()); // azerty + +var o = {a:37, f:f, g:g}; +console.log(o.f(), o.g()); // 37, azerty +</pre> + +<h3 id="As_a_DOM_event_handler">As a DOM event handler</h3> + +<p>When a function is used as an event handler, its <code>this</code> is set to the element the event fired from (some browsers do not follow this convention for listeners added dynamically with methods other than <code>addEventListener</code>).</p> + +<pre class="brush:js">// When called as a listener, turns the related element blue +function bluify(e){ + // Always true + console.log(this === e.currentTarget); + // true when currentTarget and target are the same object + console.log(this === e.target); + this.style.backgroundColor = '#A5D9F3'; +} + +// Get a list of every element in the document +var elements = document.getElementsByTagName('*'); + +// Add bluify as a click listener so when the +// element is clicked on, it turns blue +for(var i=0 ; i<elements.length ; i++){ + elements[i].addEventListener('click', bluify, false); +}</pre> + +<h3 id="In_an_in–line_event_handler">In an in–line event handler</h3> + +<p>When code is called from an in–line handler, its <code>this</code> is set to the DOM element on which the listener is placed:</p> + +<pre class="brush:js"><button onclick="alert(this.tagName.toLowerCase());"> + Show this +</button> +</pre> + +<p>The above alert shows <code>button</code>. Note however that only the outer code has its <code>this</code> set this way:</p> + +<pre class="brush:js"><button onclick="alert((function(){return this}()));"> + Show inner this +</button> +</pre> + +<p>In this case, the inner function's <code>this</code> isn't set so it returns the global/window object (i.e. the default object in non–strict mode where <code>this</code> isn't set by the call).</p> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>ECMAScript 1st Edition.</td> + <td>Standard</td> + <td>Initial definition. Implemented in JavaScript 1.0</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.1.1', 'The this keyword')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-this-keyword', 'The this keyword')}}</td> + <td>{{Spec2('ES6')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<p>{{ CompatibilityTable() }}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="See_also" name="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode">Strict mode</a></li> + <li><a href="http://bjorn.tipling.com/all-this">All this</a>, an article about <code>this</code> in different contexts</li> +</ul> |