Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”
This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.
preface
This passage mainly analyzes the cow guest pen part of the examination questions this refers to the question. First, let’s take a look at JavaScript’s this pointing problem at a macro level.
Cow guest latest front-end JS written test 100 questions
There are four different bindings for this in JavaScript (including implicit lost bindings) plus the new arrow function bindings in ES6. If you learn all of these bindings, you should have no problem pointing this. This points to a more detailed explanation, you can go to the previous blog post, there are 38 topics, detailed and complete explanation of this points to the problem.
Portal: “2W word chapter 38 interview questions” completely clear JS this pointing to the problem
- Default binding: in non-strict mode
this
Points to global objects, in strict modethis
Will be bound toundefined
- Implicit binding: meets
XXX.fn()
Format,fn
的this
Point to theXXX
. If there is a chain call,this
Always point to the object that called it last - Implicit binding loss: alias the function and run through the alias; Functions as arguments cause implicit binding loss.
- Explicit binding: Pass
call/apply/bind
Modify thethis
Point to the - New Binding: Pass
new
To call the constructor, a new object is generated, and this new object is bound to the calling functionthis
。 - Arrow function bindings: Arrow functions do not have any
this
, it’sthis
The outer scope is traced by scope chainthis
, and refers to the function definitionthis
Not at execution time
Title 1. Implicit binding and implicit binding loss
var x = 1;
var obj = {
x: 3.fun:function () {
var x = 5;
return this.x; }};var fun = obj.fun;
console.log(obj.fun(), fun());
Copy the code
parsing
JavaScript addresses for reference types are stored in stack memory, whereas real ontologies are stored in heap memory. Fun = obj.fun is equivalent to assigning the heap memory pointer to obJ. fun to fun, after which fun execution has no relationship with OBj, implicit binding loss occurs.
obj.fun()
: Implicit binding,fun
The inside of thethis
Point to theobj
To print3
fun()
Implicit binding loss:fun
Default binding, non-strict mode,this
Point to thewindow
To print1
The answer
3 1
Copy the code
Title two: Implicit binding loss
var person = {
age: 18.getAge: function() {
return this.age; }};var getAge = person.getAge
console.log(getAge())
Copy the code
Simple implicit binding loss problem
The answer
undefined
Copy the code
Title 3: Implicit binding loss
var obj = {
name:"zhangsan".sayName:function(){
console.log(this.name); }}var wfunc = obj.sayName;
obj.sayName();
wfunc();
var name = "lisi";
obj.sayName();
wfunc();
Copy the code
Simple implicit binding problem, not to go into detail.
The answer
zhangsan
undefined
zhangsan
lisi
Copy the code
Topic 4: New binding
var a = 5;
function test() {
a = 0;
console.log(a);
console.log(this.a);
var a;
console.log(a);
}
new test();
Copy the code
parsing
Using new to build a function does the following four things:
- Create an empty simple
JavaScript
The object (i.e.{}
); - Add attributes to the object created in Step 1
__proto__
Link this property to the constructor’s prototype object; - Take the object created in Step 1 as the object
this
Context; - Returns if the function does not return an object
this
.
Calling the constructor with new generates a new object and binds the new object to the calling function’s this.
console.log(a)
: Print variablesa
The current value oftestAO
ina
Variable, print0
console.log(this.a)
:new
The bindingthis
Points to a new instance object that the current title does not add toa
Properties, printundefined
console.log(a)
: Same as the first one, print0
The answer
0
undefined
0
Copy the code
Title 5: Arrow functions and explicit binding
function fun () {
return () = > {
return () = > {
return () = > {
console.log(this.name)
}
}
}
}
var f = fun.call({name: 'foo'})
var t1 = f.call({name: 'bar'}) () ()var t2 = f().call({name: 'baz'}) ()var t3 = f()().call({name: 'qux'})
Copy the code
-
The arrow function does not have this; its this is traced through the scope chain to the this of the outer scope and refers to this when the function is defined, not when it is executed.
-
The arrow function cannot modify this by calling apply bind, but can modify this indirectly by modifying this in the outer scope.
-
JavaScript is statically scoped, meaning that the function’s scope is determined at function definition, whereas the arrow function’s this is found through the scope chain, so the arrow function’s scope chain is defined.
f = fun.call({name: 'foo'})
Will:fun
Function of thethis
Point to the{name: 'foo'}
And returns an arrow function, so the arrow functionthis
Point to{name: 'foo'}
t1 = f.call({name: 'bar'})()()
: executes on the first-level arrow functioncall
Operation, invalid, currentthis
Still point to{name: 'foo'}
The second layer, the third layer are arrow functions, the third layerthis
Point to{name: 'foo'}
To printfoo
- subsequent
t2 t3
Apply to the second – and third-layer arrow functions respectivelycall
, invalid, and eventually printedfoo
。
The answer
foo
foo
foo
Copy the code
Topic 6: Arrow functions
let obj1 = {
a: 1.foo: () = > {
console.log(this.a)
}
}
// log1
console.log(obj1.foo())
const obj2 = obj1.foo
// log2
console.log(obj2())
Copy the code
parsing
obj1.foo
Is the arrow function,obj1
Object, cannot provide an outer scope, soobj.foo
The inside of thethis
Point to thewindow
obj1.foo()
: arrow function,this
Point to thewindow
To printundefined
obj2
Implicit binding lost: Printundefined
The answer
undefined
undefined
Copy the code
Directions: For this part, you are allowed 30 minutes to write a composition.
var name = 'global';
var obj = {
name: 'local'.foo: function(){
this.name = 'foo';
console.log(this.name);
}.bind(window)};var bar = new obj.foo();
setTimeout(function() {
console.log(window.name);
}, 0);
console.log(bar.name);
var bar3 = bar2 = bar;
bar2.name = 'foo2';
console.log(bar3.name);
Copy the code
parsing
The overall quality of this topic is still very high, first of all, let’s put the knowledge involved in a list:
bind
It is explicitly bound and will changethis
Point, butbind()
The function does not execute the function immediately, but returns a new functionsetTimeout
An asynchronous task can be executed only after the synchronization task is complete- Binding priority: New binding > Explicit binding > Implicit binding > Default binding
parsing
obj.foo
Will itthis
throughbind
The explicit binding iswindow
, butbind
Not immediatelyvar bar = new obj.foo()
:new
The binding priority is greater thanbind
, sobind
It failed, and nowthis
Point to thenew
Instance, thereforeobj.foo
The inside of theconsole
printfoo
bar
是new obj.foo()
An instance of theconsole.log(bar.name)
printfoo
setTimeout
Asynchronous tasks that wait until synchronization is complete before calling its callbackbar3 = bar2 = bar
That will beBar2, bar3, bar
The address of thebar
The space that I’m pointing to.bar2.name = 'foo2'
To change the value of the address pointing to heap memoryconsole.log(bar3.name)
Since all three variables point to the same block of address,bar3
To modify thename
,bar3
Also change, printfoo2
setTimeout
The callback is executed and printedglobal
The answer
foo
foo
foo2
global
Copy the code
Topic 7: Comprehensive topic modification
Although the sixth topic is of good quality, I feel that there are several places that people are not satisfied with. Let’s change the topic.
Change 1: Remove the new binding
var name = 'global';
var obj = {
name: 'local'.foo: function(){
this.name = 'foo';
console.log(this.name);
}.bind(window)}; obj.foo();setTimeout(function() {
console.log(this.name);
}, 0);
console.log(name);
Copy the code
obj.foo
No modifications were made to itthis
throughbind
The explicit binding iswindow
, butbind
Not immediatelyobj.foo()
Execute, explicit binding takes precedence over implicit binding, so at this pointfoo
functionthis -> window
this.name
The equivalent ofwindow.name
, modified globalname
Variable value, printfoo
setTimeout
Callback and other synchronization code execution is complete- global
name
Has been modified tofoo
To printfoo
- perform
setTimeout
The callback, default binding, printsfoo
The answer
foo
foo
foo
Copy the code
Change 1: change bind to call
var name = 'global';
var obj = {
name: 'local'.foo: function(){
this.name = 'foo';
console.log(this.name); }}; obj.foo.call(window);
var bar = new obj.foo();
setTimeout(function() {
console.log(window.name);
}, 0);
console.log(bar.name);
var bar3 = bar2 = bar;
bar2.name = 'foo2';
console.log(bar3.name);
Copy the code
The difference between call and bind is that the call function executes immediately
So obj.foo.call(window) immediately executes the function and also modifies the global name value. The other parts are similar to those mentioned above, so I won’t repeat them.
The answer
foo
foo
foo
foo2
foo
Copy the code
Past wonderful articles
- Cow guest latest front-end JS written test 100 questions
- A thorough understanding of prototypes and prototype chains in JavaScript
- JavaScript precompilation learning
- Complete understanding of EventLoop in JavaScript
- “2W word big chapter 38 interview questions” completely clear JS this pointing to the problem