Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Post History
This MDN link might help to explain that: When a function is called as a method of an object, its this is set to the object the method is called on. Which is your first example (calling obj.a())....
Answer
#7: Post edited
- [This MDN link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#As_an_object_method) might help to explain that:
- > _When a function is called as a method of an object, its `this` is set to the object the method is called on._
- Which is your first example (calling `obj.a()`). But the link above also mentions that "*this behavior is not at all affected by how or where the function was defined*". So I could do the opposite of what you did, and create the function outside the object and then attach it:
- ```javascript
- let obj = {
- b: 'hello'
- };
- function f() {
- return (this === obj) ? this.b : 'bye';
- }
- obj.a = f;
- console.log(obj.a()); // hello
- console.log(f()); // bye
- ```
- That's because what really matters is **how** you invoke the function. If called from a member of the object, the `this` value is set to the object, regardless of where the function was defined. So calling it in a "non-object" context doesn't set `this` to the object.
- BTW, calling `(obj.a)()` is the same as `obj.a()` because in this case the first pair of parenthesis is redundant (`(obj.a)` evaluates to the `obj.a` function, and `obj.a === (obj.a)` is `true`). But it's not the same as setting a variable `f = obj.a` and then calling `f()` because, as said above, how the function is called influences the value of `this`, and by calling `f()`, I'm not invoking the function as a method of an object.
- To accomplish the behaviour of "preserving" `this`, you could use [`bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) or [`call`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call), which are two ways of controlling which value of `this` the function sees:
- ```
- let obj = {
- a: function() { return (this === obj) ? this.b : 'bye'; },
- b: 'hello'
- };
- let a = obj.a;
- console.log(a()); // bye
- // with call, using "obj" as the "this" value
- console.log(a.call(obj)); // hello
- // bind, returns another function that uses "obj" as the "this" value
- let boundFunc = obj.a.bind(obj);
- console.log(boundFunc()); // hello
- ```
- ---
- I'm not sure about the exact terminology, but [this section of the spec](https://tc39.es/ecma262/#sec-this-keyword-runtime-semantics-evaluation) mentions the `ResolveThisBinding` operation, [whose definition says](https://tc39.es/ecma262/#sec-resolvethisbinding): "*It determines the **binding** of the keyword `this` using the LexicalEnvironment of the running execution context.*" - and `ResolveThisBinding` operations calls `GetThisEnvironment`, [whose definition says](https://tc39.es/ecma262/#sec-getthisenvironment): "*It finds the Environment Record that currently supplies the **binding** of the keyword `this`*".
So I guess "_binding_" would be an appropriate term.![JS this is confusing](https://software.codidact.com/uploads/CEtdDJedzP2KRQag3UqjgUqa)
- [This MDN link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#As_an_object_method) might help to explain that:
- > _When a function is called as a method of an object, its `this` is set to the object the method is called on._
- Which is your first example (calling `obj.a()`). But the link above also mentions that "*this behavior is not at all affected by how or where the function was defined*". So I could do the opposite of what you did, and create the function outside the object and then attach it:
- ```javascript
- let obj = {
- b: 'hello'
- };
- function f() {
- return (this === obj) ? this.b : 'bye';
- }
- obj.a = f;
- console.log(obj.a()); // hello
- console.log(f()); // bye
- ```
- That's because what really matters is **how** you invoke the function. If called from a member of the object, the `this` value is set to the object, regardless of where the function was defined. So calling it in a "non-object" context doesn't set `this` to the object.
- BTW, calling `(obj.a)()` is the same as `obj.a()` because in this case the first pair of parenthesis is redundant (`(obj.a)` evaluates to the `obj.a` function, and `obj.a === (obj.a)` is `true`). But it's not the same as setting a variable `f = obj.a` and then calling `f()` because, as said above, how the function is called influences the value of `this`, and by calling `f()`, I'm not invoking the function as a method of an object.
- To accomplish the behaviour of "preserving" `this`, you could use [`bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) or [`call`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call), which are two ways of controlling which value of `this` the function sees:
- ```
- let obj = {
- a: function() { return (this === obj) ? this.b : 'bye'; },
- b: 'hello'
- };
- let a = obj.a;
- console.log(a()); // bye
- // with call, using "obj" as the "this" value
- console.log(a.call(obj)); // hello
- // bind, returns another function that uses "obj" as the "this" value
- let boundFunc = obj.a.bind(obj);
- console.log(boundFunc()); // hello
- ```
- ---
- I'm not sure about the exact terminology, but [this section of the spec](https://tc39.es/ecma262/#sec-this-keyword-runtime-semantics-evaluation) mentions the `ResolveThisBinding` operation, [whose definition says](https://tc39.es/ecma262/#sec-resolvethisbinding): "*It determines the **binding** of the keyword `this` using the LexicalEnvironment of the running execution context.*" - and `ResolveThisBinding` operations calls `GetThisEnvironment`, [whose definition says](https://tc39.es/ecma262/#sec-getthisenvironment): "*It finds the Environment Record that currently supplies the **binding** of the keyword `this`*".
- So I guess "_binding_" would be an appropriate term.
#6: Post edited
- [This MDN link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#As_an_object_method) might help to explain that:
- > _When a function is called as a method of an object, its `this` is set to the object the method is called on._
- Which is your first example (calling `obj.a()`). But the link above also mentions that "*this behavior is not at all affected by how or where the function was defined*". So I could do the opposite of what you did, and create the function outside the object and then attach it:
- ```javascript
- let obj = {
- b: 'hello'
- };
- function f() {
- return (this === obj) ? this.b : 'bye';
- }
- obj.a = f;
- console.log(obj.a()); // hello
- console.log(f()); // bye
- ```
- That's because what really matters is **how** you invoke the function. If called from a member of the object, the `this` value is set to the object, regardless of where the function was defined. So calling it in a "non-object" context doesn't set `this` to the object.
- BTW, calling `(obj.a)()` is the same as `obj.a()` because in this case the first pair of parenthesis is redundant (`(obj.a)` evaluates to the `obj.a` function, and `obj.a === (obj.a)` is `true`). But it's not the same as setting a variable `f = obj.a` and then calling `f()` because, as said above, how the function is called influences the value of `this`, and by calling `f()`, I'm not invoking the function as a method of an object.
- To accomplish the behaviour of "preserving" `this`, you could use [`bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) or [`call`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call), which are two ways of controlling which value of `this` the function sees:
- ```
- let obj = {
a: function() {return (this === obj) ? this.b : 'bye';},- b: 'hello'
- };
- let a = obj.a;
- console.log(a()); // bye
- // with call, using "obj" as the "this" value
- console.log(a.call(obj)); // hello
// bind, returns another function that use "obj" as the "this" value- let boundFunc = obj.a.bind(obj);
- console.log(boundFunc()); // hello
- ```
- ---
- I'm not sure about the exact terminology, but [this section of the spec](https://tc39.es/ecma262/#sec-this-keyword-runtime-semantics-evaluation) mentions the `ResolveThisBinding` operation, [whose definition says](https://tc39.es/ecma262/#sec-resolvethisbinding): "*It determines the **binding** of the keyword `this` using the LexicalEnvironment of the running execution context.*" - and `ResolveThisBinding` operations calls `GetThisEnvironment`, [whose definition says](https://tc39.es/ecma262/#sec-getthisenvironment): "*It finds the Environment Record that currently supplies the **binding** of the keyword `this`*".
- So I guess "_binding_" would be an appropriate term.
- ![JS this is confusing](https://software.codidact.com/uploads/CEtdDJedzP2KRQag3UqjgUqa)
- [This MDN link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#As_an_object_method) might help to explain that:
- > _When a function is called as a method of an object, its `this` is set to the object the method is called on._
- Which is your first example (calling `obj.a()`). But the link above also mentions that "*this behavior is not at all affected by how or where the function was defined*". So I could do the opposite of what you did, and create the function outside the object and then attach it:
- ```javascript
- let obj = {
- b: 'hello'
- };
- function f() {
- return (this === obj) ? this.b : 'bye';
- }
- obj.a = f;
- console.log(obj.a()); // hello
- console.log(f()); // bye
- ```
- That's because what really matters is **how** you invoke the function. If called from a member of the object, the `this` value is set to the object, regardless of where the function was defined. So calling it in a "non-object" context doesn't set `this` to the object.
- BTW, calling `(obj.a)()` is the same as `obj.a()` because in this case the first pair of parenthesis is redundant (`(obj.a)` evaluates to the `obj.a` function, and `obj.a === (obj.a)` is `true`). But it's not the same as setting a variable `f = obj.a` and then calling `f()` because, as said above, how the function is called influences the value of `this`, and by calling `f()`, I'm not invoking the function as a method of an object.
- To accomplish the behaviour of "preserving" `this`, you could use [`bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) or [`call`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call), which are two ways of controlling which value of `this` the function sees:
- ```
- let obj = {
- a: function() { return (this === obj) ? this.b : 'bye'; },
- b: 'hello'
- };
- let a = obj.a;
- console.log(a()); // bye
- // with call, using "obj" as the "this" value
- console.log(a.call(obj)); // hello
- // bind, returns another function that uses "obj" as the "this" value
- let boundFunc = obj.a.bind(obj);
- console.log(boundFunc()); // hello
- ```
- ---
- I'm not sure about the exact terminology, but [this section of the spec](https://tc39.es/ecma262/#sec-this-keyword-runtime-semantics-evaluation) mentions the `ResolveThisBinding` operation, [whose definition says](https://tc39.es/ecma262/#sec-resolvethisbinding): "*It determines the **binding** of the keyword `this` using the LexicalEnvironment of the running execution context.*" - and `ResolveThisBinding` operations calls `GetThisEnvironment`, [whose definition says](https://tc39.es/ecma262/#sec-getthisenvironment): "*It finds the Environment Record that currently supplies the **binding** of the keyword `this`*".
- So I guess "_binding_" would be an appropriate term.
- ![JS this is confusing](https://software.codidact.com/uploads/CEtdDJedzP2KRQag3UqjgUqa)
#5: Post edited
- [This MDN link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#As_an_object_method) might help to explain that:
- > _When a function is called as a method of an object, its `this` is set to the object the method is called on._
Which is your first example (calling `obj.a()`). But the link above also mentions that "*this behavior is not at all affected by how or where the function was defined*". So I could do the opposite of what you did: create the function outside the object and then attach it:- ```javascript
- let obj = {
- b: 'hello'
- };
- function f() {
- return (this === obj) ? this.b : 'bye';
- }
- obj.a = f;
- console.log(obj.a()); // hello
- console.log(f()); // bye
- ```
- That's because what really matters is **how** you invoke the function. If called from a member of the object, the `this` value is set to the object, regardless of where the function was defined. So calling it in a "non-object" context doesn't set `this` to the object.
- BTW, calling `(obj.a)()` is the same as `obj.a()` because in this case the first pair of parenthesis is redundant (`(obj.a)` evaluates to the `obj.a` function, and `obj.a === (obj.a)` is `true`). But it's not the same as setting a variable `f = obj.a` and then calling `f()` because, as said above, how the function is called influences the value of `this`, and by calling `f()`, I'm not invoking the function as a method of an object.
- To accomplish the behaviour of "preserving" `this`, you could use [`bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) or [`call`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call), which are two ways of controlling which value of `this` the function sees:
- ```
- let obj = {
- a: function() {
- return (this === obj) ? this.b : 'bye';
- },
- b: 'hello'
- };
- let a = obj.a;
- console.log(a()); // bye
// with call, use "obj" as the "this" value- console.log(a.call(obj)); // hello
- // bind, returns another function that use "obj" as the "this" value
- let boundFunc = obj.a.bind(obj);
- console.log(boundFunc()); // hello
- ```
- ---
I'm not sure about the exact terminology, but [this section of the spec](https://tc39.es/ecma262/#sec-this-keyword-runtime-semantics-evaluation) mentions the `ResolveThisBinding` operation, [whose definition says](https://tc39.es/ecma262/#sec-resolvethisbinding): "*It determines the **binding** of the keyword `this` using the LexicalEnvironment of the running execution context.*" - and `ResolveThisBinding` operations calls [`GetThisEnvironment`](https://tc39.es/ecma262/#sec-getthisenvironment), whose definition says: "*It finds the Environment Record that currently supplies the binding of the keyword `this`*".So I guess "binding" would be the appropriate term.- ![JS this is confusing](https://software.codidact.com/uploads/CEtdDJedzP2KRQag3UqjgUqa)
- [This MDN link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#As_an_object_method) might help to explain that:
- > _When a function is called as a method of an object, its `this` is set to the object the method is called on._
- Which is your first example (calling `obj.a()`). But the link above also mentions that "*this behavior is not at all affected by how or where the function was defined*". So I could do the opposite of what you did, and create the function outside the object and then attach it:
- ```javascript
- let obj = {
- b: 'hello'
- };
- function f() {
- return (this === obj) ? this.b : 'bye';
- }
- obj.a = f;
- console.log(obj.a()); // hello
- console.log(f()); // bye
- ```
- That's because what really matters is **how** you invoke the function. If called from a member of the object, the `this` value is set to the object, regardless of where the function was defined. So calling it in a "non-object" context doesn't set `this` to the object.
- BTW, calling `(obj.a)()` is the same as `obj.a()` because in this case the first pair of parenthesis is redundant (`(obj.a)` evaluates to the `obj.a` function, and `obj.a === (obj.a)` is `true`). But it's not the same as setting a variable `f = obj.a` and then calling `f()` because, as said above, how the function is called influences the value of `this`, and by calling `f()`, I'm not invoking the function as a method of an object.
- To accomplish the behaviour of "preserving" `this`, you could use [`bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) or [`call`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call), which are two ways of controlling which value of `this` the function sees:
- ```
- let obj = {
- a: function() {
- return (this === obj) ? this.b : 'bye';
- },
- b: 'hello'
- };
- let a = obj.a;
- console.log(a()); // bye
- // with call, using "obj" as the "this" value
- console.log(a.call(obj)); // hello
- // bind, returns another function that use "obj" as the "this" value
- let boundFunc = obj.a.bind(obj);
- console.log(boundFunc()); // hello
- ```
- ---
- I'm not sure about the exact terminology, but [this section of the spec](https://tc39.es/ecma262/#sec-this-keyword-runtime-semantics-evaluation) mentions the `ResolveThisBinding` operation, [whose definition says](https://tc39.es/ecma262/#sec-resolvethisbinding): "*It determines the **binding** of the keyword `this` using the LexicalEnvironment of the running execution context.*" - and `ResolveThisBinding` operations calls `GetThisEnvironment`, [whose definition says](https://tc39.es/ecma262/#sec-getthisenvironment): "*It finds the Environment Record that currently supplies the **binding** of the keyword `this`*".
- So I guess "_binding_" would be an appropriate term.
- ![JS this is confusing](https://software.codidact.com/uploads/CEtdDJedzP2KRQag3UqjgUqa)
#4: Post edited
- [This MDN link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#As_an_object_method) might help to explain that:
- > _When a function is called as a method of an object, its `this` is set to the object the method is called on._
- Which is your first example (calling `obj.a()`). But the link above also mentions that "*this behavior is not at all affected by how or where the function was defined*". So I could do the opposite of what you did: create the function outside the object and then attach it:
- ```javascript
- let obj = {
- b: 'hello'
- };
- function f() {
- return (this === obj) ? this.b : 'bye';
- }
- obj.a = f;
- console.log(obj.a()); // hello
- console.log(f()); // bye
- ```
- That's because what really matters is **how** you invoke the function. If called from a member of the object, the `this` value is set to the object, regardless of where the function was defined. So calling it in a "non-object" context doesn't set `this` to the object.
- BTW, calling `(obj.a)()` is the same as `obj.a()` because in this case the first pair of parenthesis is redundant (`(obj.a)` evaluates to the `obj.a` function, and `obj.a === (obj.a)` is `true`). But it's not the same as setting a variable `f = obj.a` and then calling `f()` because, as said above, how the function is called influences the value of `this`, and by calling `f()`, I'm not invoking the function as a method of an object.
To accomplish that behaviour of "preserving" `this`, you could use `bind` or `call`, which are two ways of controlling which value of `this` the function sees:- ```
- let obj = {
- a: function() {
- return (this === obj) ? this.b : 'bye';
- },
- b: 'hello'
- };
- let a = obj.a;
- console.log(a()); // bye
- // with call, use "obj" as the "this" value
- console.log(a.call(obj)); // hello
- // bind, returns another function that use "obj" as the "this" value
- let boundFunc = obj.a.bind(obj);
- console.log(boundFunc()); // hello
- ```
- ---
- I'm not sure about the exact terminology, but [this section of the spec](https://tc39.es/ecma262/#sec-this-keyword-runtime-semantics-evaluation) mentions the `ResolveThisBinding` operation, [whose definition says](https://tc39.es/ecma262/#sec-resolvethisbinding): "*It determines the **binding** of the keyword `this` using the LexicalEnvironment of the running execution context.*" - and `ResolveThisBinding` operations calls [`GetThisEnvironment`](https://tc39.es/ecma262/#sec-getthisenvironment), whose definition says: "*It finds the Environment Record that currently supplies the binding of the keyword `this`*".
- So I guess "binding" would be the appropriate term.
- ![JS this is confusing](https://software.codidact.com/uploads/CEtdDJedzP2KRQag3UqjgUqa)
- [This MDN link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#As_an_object_method) might help to explain that:
- > _When a function is called as a method of an object, its `this` is set to the object the method is called on._
- Which is your first example (calling `obj.a()`). But the link above also mentions that "*this behavior is not at all affected by how or where the function was defined*". So I could do the opposite of what you did: create the function outside the object and then attach it:
- ```javascript
- let obj = {
- b: 'hello'
- };
- function f() {
- return (this === obj) ? this.b : 'bye';
- }
- obj.a = f;
- console.log(obj.a()); // hello
- console.log(f()); // bye
- ```
- That's because what really matters is **how** you invoke the function. If called from a member of the object, the `this` value is set to the object, regardless of where the function was defined. So calling it in a "non-object" context doesn't set `this` to the object.
- BTW, calling `(obj.a)()` is the same as `obj.a()` because in this case the first pair of parenthesis is redundant (`(obj.a)` evaluates to the `obj.a` function, and `obj.a === (obj.a)` is `true`). But it's not the same as setting a variable `f = obj.a` and then calling `f()` because, as said above, how the function is called influences the value of `this`, and by calling `f()`, I'm not invoking the function as a method of an object.
- To accomplish the behaviour of "preserving" `this`, you could use [`bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) or [`call`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call), which are two ways of controlling which value of `this` the function sees:
- ```
- let obj = {
- a: function() {
- return (this === obj) ? this.b : 'bye';
- },
- b: 'hello'
- };
- let a = obj.a;
- console.log(a()); // bye
- // with call, use "obj" as the "this" value
- console.log(a.call(obj)); // hello
- // bind, returns another function that use "obj" as the "this" value
- let boundFunc = obj.a.bind(obj);
- console.log(boundFunc()); // hello
- ```
- ---
- I'm not sure about the exact terminology, but [this section of the spec](https://tc39.es/ecma262/#sec-this-keyword-runtime-semantics-evaluation) mentions the `ResolveThisBinding` operation, [whose definition says](https://tc39.es/ecma262/#sec-resolvethisbinding): "*It determines the **binding** of the keyword `this` using the LexicalEnvironment of the running execution context.*" - and `ResolveThisBinding` operations calls [`GetThisEnvironment`](https://tc39.es/ecma262/#sec-getthisenvironment), whose definition says: "*It finds the Environment Record that currently supplies the binding of the keyword `this`*".
- So I guess "binding" would be the appropriate term.
- ![JS this is confusing](https://software.codidact.com/uploads/CEtdDJedzP2KRQag3UqjgUqa)
#3: Post edited
- [This MDN link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#As_an_object_method) might help to explain that:
- > _When a function is called as a method of an object, its `this` is set to the object the method is called on._
- Which is your first example (calling `obj.a()`). But the link above also mentions that "*this behavior is not at all affected by how or where the function was defined*". So I could do the opposite of what you did: create the function outside the object and then attach it:
- ```javascript
- let obj = {
- b: 'hello'
- };
- function f() {
- return (this === obj) ? this.b : 'bye';
- }
- obj.a = f;
- console.log(obj.a()); // hello
- console.log(f()); // bye
- ```
- That's because what really matters is **how** you invoke the function. If called from a member of the object, the `this` value is set to the object, regardless of where the function was defined. So calling it in a "non-object" context doesn't set `this` to the object.
- BTW, calling `(obj.a)()` is the same as `obj.a()` because in this case the first pair of parenthesis is redundant (`(obj.a)` evaluates to the `obj.a` function, and `obj.a === (obj.a)` is `true`). But it's not the same as setting a variable `f = obj.a` and then calling `f()` because, as said above, how the function is called influences the value of `this`, and by calling `f()`, I'm not invoking the function as a method of an object.
- To accomplish that behaviour of "preserving" `this`, you could use `bind` or `call`, which are two ways of controlling which value of `this` the function sees:
- ```
- let obj = {
- a: function() {
- return (this === obj) ? this.b : 'bye';
- },
- b: 'hello'
- };
- let a = obj.a;
- console.log(a()); // bye
- // with call, use "obj" as the "this" value
- console.log(a.call(obj)); // hello
- // bind, returns another function that use "obj" as the "this" value
- let boundFunc = obj.a.bind(obj);
- console.log(boundFunc()); // hello
- ```
- ---
- I'm not sure about the exact terminology, but [this section of the spec](https://tc39.es/ecma262/#sec-this-keyword-runtime-semantics-evaluation) mentions the `ResolveThisBinding` operation, [whose definition says](https://tc39.es/ecma262/#sec-resolvethisbinding): "*It determines the **binding** of the keyword `this` using the LexicalEnvironment of the running execution context.*" - and `ResolveThisBinding` operations calls [`GetThisEnvironment`](https://tc39.es/ecma262/#sec-getthisenvironment), whose definition says: "*It finds the Environment Record that currently supplies the binding of the keyword `this`*".
So I guess "binding" would be the appropriate term.
- [This MDN link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#As_an_object_method) might help to explain that:
- > _When a function is called as a method of an object, its `this` is set to the object the method is called on._
- Which is your first example (calling `obj.a()`). But the link above also mentions that "*this behavior is not at all affected by how or where the function was defined*". So I could do the opposite of what you did: create the function outside the object and then attach it:
- ```javascript
- let obj = {
- b: 'hello'
- };
- function f() {
- return (this === obj) ? this.b : 'bye';
- }
- obj.a = f;
- console.log(obj.a()); // hello
- console.log(f()); // bye
- ```
- That's because what really matters is **how** you invoke the function. If called from a member of the object, the `this` value is set to the object, regardless of where the function was defined. So calling it in a "non-object" context doesn't set `this` to the object.
- BTW, calling `(obj.a)()` is the same as `obj.a()` because in this case the first pair of parenthesis is redundant (`(obj.a)` evaluates to the `obj.a` function, and `obj.a === (obj.a)` is `true`). But it's not the same as setting a variable `f = obj.a` and then calling `f()` because, as said above, how the function is called influences the value of `this`, and by calling `f()`, I'm not invoking the function as a method of an object.
- To accomplish that behaviour of "preserving" `this`, you could use `bind` or `call`, which are two ways of controlling which value of `this` the function sees:
- ```
- let obj = {
- a: function() {
- return (this === obj) ? this.b : 'bye';
- },
- b: 'hello'
- };
- let a = obj.a;
- console.log(a()); // bye
- // with call, use "obj" as the "this" value
- console.log(a.call(obj)); // hello
- // bind, returns another function that use "obj" as the "this" value
- let boundFunc = obj.a.bind(obj);
- console.log(boundFunc()); // hello
- ```
- ---
- I'm not sure about the exact terminology, but [this section of the spec](https://tc39.es/ecma262/#sec-this-keyword-runtime-semantics-evaluation) mentions the `ResolveThisBinding` operation, [whose definition says](https://tc39.es/ecma262/#sec-resolvethisbinding): "*It determines the **binding** of the keyword `this` using the LexicalEnvironment of the running execution context.*" - and `ResolveThisBinding` operations calls [`GetThisEnvironment`](https://tc39.es/ecma262/#sec-getthisenvironment), whose definition says: "*It finds the Environment Record that currently supplies the binding of the keyword `this`*".
- So I guess "binding" would be the appropriate term.
- ![JS this is confusing](https://software.codidact.com/uploads/CEtdDJedzP2KRQag3UqjgUqa)
#2: Post edited
- [This MDN link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#As_an_object_method) might help to explain that:
- > _When a function is called as a method of an object, its `this` is set to the object the method is called on._
- Which is your first example (calling `obj.a()`). But the link above also mentions that "*this behavior is not at all affected by how or where the function was defined*". So I could do the opposite of what you did: create the function outside the object and then attach it:
- ```javascript
- let obj = {
- b: 'hello'
- };
- function f() {
- return (this === obj) ? this.b : 'bye';
- }
- obj.a = f;
- console.log(obj.a()); // hello
- console.log(f()); // bye
- ```
- That's because what really matters is **how** you invoke the function. If called from a member of the object, the `this` value is set to the object, regardless of where the function was defined. So calling it in a "non-object" context doesn't set `this` to the object.
BTW, calling `(obj.a)()` is the same as `obj.a()` because in this case the first pair of parenthesis is redundant (`(obj.a)` evaluates to the `obj.a` function). But it's not the same as setting a variable `f = obj.a` and then calling `f()` because, as said above, how the function is called influences the value of `this`, and by calling `f()`, I'm not invoking the function as a method of an object.- ---
- I'm not sure about the exact terminology, but [this section of the spec](https://tc39.es/ecma262/#sec-this-keyword-runtime-semantics-evaluation) mentions the `ResolveThisBinding` operation, [whose definition says](https://tc39.es/ecma262/#sec-resolvethisbinding): "*It determines the **binding** of the keyword `this` using the LexicalEnvironment of the running execution context.*" - and `ResolveThisBinding` operations calls [`GetThisEnvironment`](https://tc39.es/ecma262/#sec-getthisenvironment), whose definition says: "*It finds the Environment Record that currently supplies the binding of the keyword `this`*".
- So I guess "binding" would be the appropriate term.
- [This MDN link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#As_an_object_method) might help to explain that:
- > _When a function is called as a method of an object, its `this` is set to the object the method is called on._
- Which is your first example (calling `obj.a()`). But the link above also mentions that "*this behavior is not at all affected by how or where the function was defined*". So I could do the opposite of what you did: create the function outside the object and then attach it:
- ```javascript
- let obj = {
- b: 'hello'
- };
- function f() {
- return (this === obj) ? this.b : 'bye';
- }
- obj.a = f;
- console.log(obj.a()); // hello
- console.log(f()); // bye
- ```
- That's because what really matters is **how** you invoke the function. If called from a member of the object, the `this` value is set to the object, regardless of where the function was defined. So calling it in a "non-object" context doesn't set `this` to the object.
- BTW, calling `(obj.a)()` is the same as `obj.a()` because in this case the first pair of parenthesis is redundant (`(obj.a)` evaluates to the `obj.a` function, and `obj.a === (obj.a)` is `true`). But it's not the same as setting a variable `f = obj.a` and then calling `f()` because, as said above, how the function is called influences the value of `this`, and by calling `f()`, I'm not invoking the function as a method of an object.
- To accomplish that behaviour of "preserving" `this`, you could use `bind` or `call`, which are two ways of controlling which value of `this` the function sees:
- ```
- let obj = {
- a: function() {
- return (this === obj) ? this.b : 'bye';
- },
- b: 'hello'
- };
- let a = obj.a;
- console.log(a()); // bye
- // with call, use "obj" as the "this" value
- console.log(a.call(obj)); // hello
- // bind, returns another function that use "obj" as the "this" value
- let boundFunc = obj.a.bind(obj);
- console.log(boundFunc()); // hello
- ```
- ---
- I'm not sure about the exact terminology, but [this section of the spec](https://tc39.es/ecma262/#sec-this-keyword-runtime-semantics-evaluation) mentions the `ResolveThisBinding` operation, [whose definition says](https://tc39.es/ecma262/#sec-resolvethisbinding): "*It determines the **binding** of the keyword `this` using the LexicalEnvironment of the running execution context.*" - and `ResolveThisBinding` operations calls [`GetThisEnvironment`](https://tc39.es/ecma262/#sec-getthisenvironment), whose definition says: "*It finds the Environment Record that currently supplies the binding of the keyword `this`*".
- So I guess "binding" would be the appropriate term.
#1: Initial revision
[This MDN link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#As_an_object_method) might help to explain that: > _When a function is called as a method of an object, its `this` is set to the object the method is called on._ Which is your first example (calling `obj.a()`). But the link above also mentions that "*this behavior is not at all affected by how or where the function was defined*". So I could do the opposite of what you did: create the function outside the object and then attach it: ```javascript let obj = { b: 'hello' }; function f() { return (this === obj) ? this.b : 'bye'; } obj.a = f; console.log(obj.a()); // hello console.log(f()); // bye ``` That's because what really matters is **how** you invoke the function. If called from a member of the object, the `this` value is set to the object, regardless of where the function was defined. So calling it in a "non-object" context doesn't set `this` to the object. BTW, calling `(obj.a)()` is the same as `obj.a()` because in this case the first pair of parenthesis is redundant (`(obj.a)` evaluates to the `obj.a` function). But it's not the same as setting a variable `f = obj.a` and then calling `f()` because, as said above, how the function is called influences the value of `this`, and by calling `f()`, I'm not invoking the function as a method of an object. --- I'm not sure about the exact terminology, but [this section of the spec](https://tc39.es/ecma262/#sec-this-keyword-runtime-semantics-evaluation) mentions the `ResolveThisBinding` operation, [whose definition says](https://tc39.es/ecma262/#sec-resolvethisbinding): "*It determines the **binding** of the keyword `this` using the LexicalEnvironment of the running execution context.*" - and `ResolveThisBinding` operations calls [`GetThisEnvironment`](https://tc39.es/ecma262/#sec-getthisenvironment), whose definition says: "*It finds the Environment Record that currently supplies the binding of the keyword `this`*". So I guess "binding" would be the appropriate term.