What is this?
In object-oriented programming languages, this refers to the current object and represents a reference to the current object, that is, a pointer to an address.
Second, the benefits brought by this
// If this is not present:
var obj1 = {
name: "jack1".eat: function () {
console.log(obj1.name); }}var obj2 = {
name: "jack2".eat: function () {
console.log(obj2.name);
}
}
obj1.eat(); //obj1
obj2.eat(); //obj2
// 有this
function eat() {
console.log(this.name);
}
var obj3 = {
name: "jack3",
eat
}
var obj4 = {
name: "jack4",
eat
}
obj3.eat(); //obj3
obj4.eat(); //obj4
Copy the code
C. this D. this
This represents a reference to the current object, which is determined at call time. When I first got into JavaScript, I heard someone say that the “this” refers to whoever calls me, I will refer to him. I also thought that this sentence was the Bible. Until you encounter call, apply, arrow functions, etc., this bible is no longer applicable and you have to consider relearning this. This article considers that in the context of a browser, node’s global variables are somewhat different.
The direction of this can be divided into several cases:
- The default binding
- Implicit binding
- According to the binding
- The new binding
- Arrow function
Personally, the default binding is a type of implicit binding.
Default binding
- Direct calls to global functions
function foo() {
console.log(this); //window
}
foo();
Copy the code
- Function internal call
function foo1() {
console.log(this); //window
}
function foo2() {
console.log(this); //window
foo1();
}
foo2();
Copy the code
- Object property reference
var obj = {
foo: function() {
console.log(this); //window}}var fn = obj.foo; //fn references the methods of obj.foo
fn();
Copy the code
Why is the default binding implicit?
The browser will go through the pre-parsing process when parsing Javascript code. In the pre-parsing process, a Global Object will be created. The functions defined in the outermost layer of Javascript will be mounted under the Global Object. But the value of window is this, which is why we say that the browser’s global object is window, essentially because window is just a reference to the global object.
function foo() {
console.log(this);
}
// Preparse to generate the global object GO
// GO = {
// foo,
// window: this
// }
foo(); The //foo invocation actually finds go.foo, which is window.foo
window.foo(); // This returns the same result as above, pointing to window
Copy the code
Implicit binding
Implicit binding is a fragment in the Bible where I point to whoever calls me. Display binding failed again… Insufficient priority)
- Method as an attribute of the object
var obj = {
name: "jack".foo: function() {
console.log(this); //obj
}
}
obj.foo();
Copy the code
- Methods are properties of another object
var obj1 = {
foo: function() {
console.log(this); }}var obj2 = {
name: "jack2".foo: obj1.foo
}
obj2.foo(); //obj2
Copy the code
Display binding
- call
var obj = {
name: "jack"
}
function sum(a,b) {
console.log(a + b);
console.log(this);
}
sum.call(obj,1.2); //3 obj
Copy the code
- apply
var obj = {
name: "jack"
}
function sum(a,b) {
console.log(a + b);
console.log(this);
}
sum.apply(obj,[1.2]); //3 obj
Copy the code
Call differs from apply only in the form in which arguments are passed. 3. bind
var obj = {
name: "jack"
}
function sum(a,b) {
console.log(a + b);
console.log(this);
}
var sum2 = sum.bind(obj,1);
sum2(2); //3 obj
Copy the code
Bind method parameter passing is a process of parameter collection, and it is also a kind of function curryification, which I will share with you later. The bind method has no effect on the arrow function.
Vii. New binding
The procedure for calling a function with the new operator:
- Creates an empty object in memory.
- The [[prototype]] property inside this object is assigned to the constructor’s Prototype property.
- The this inside the constructor points to the newly created object.
- The code that executes the function body.
- If the function does not return a non-empty object, the newly created object is returned.
function Person(name,age) {
this.name = name;
this.age = age;
}
var p = new Person("jack".18);
console.log(p); //Person {name: 'jack', age: 18}
Copy the code
This in the arrow function
Instead of using the four standard rules for this (i.e., not binding this), the arrow function determines this based on its outer scope.
var name = "Outside the name";
var obj = {
name: "jack".foo: () = > {
console.log(this.name);
}
}
obj.foo();
Copy the code
This binding priority
- Display binding over implicit binding
var obj1 = {
name: "obj1".foo: function() {
console.log(this.name); }}var obj2 = {
name: "obj2"
}
obj1.foo.call(obj2); //obj2
Copy the code
- New takes precedence over implicit binding
var obj = {
name: "jack".foo: function(name) {
this.name = name;
console.log(this.name); }}new obj.foo("foo"); //foo
Copy the code
- The new binding is higher than the display binding
function foo(name) {
this.name = name;
console.log(this.name);
}
var obj = {
name: "jack"
}
var bar = foo.bind(obj);
new bar("foo"); //foo
Copy the code
10. Special binding null,undefined
Automatically bind this to a global object when null/undefined is passed
function foo() {
console.log(this);
}
foo.call(null); //window
foo.call(undefined); //window
Copy the code
Custom call
The Call method is a Function instance method, so it is defined on top of the prototype of the Function constructor. I’ll share a section on prototypes and prototype chains later.
Function.prototype.myCall = function(obj,... args) {
obj = obj || window;
let key = Symbol("key");
obj[key] = this; // This refers to the function that calls myCall
letresult = obj[key](... args);delete obj[key];
return result;
}
function foo(age) {
console.log(this.name,age);
}
foo.myCall({name: "jack"},18);
Copy the code
Xii. Customize apply
Call and apply are just the difference between passing parameters, and the implementation idea is exactly the same
Function.prototype.myApply = function(obj,args) {
obj = obj || window;
let key = Symbol("key");
obj[key] = this; // This refers to the function that calls myApply
letresult = obj[key](... args);delete obj[key];
return result;
}
function foo(age) {
console.log(this.name,age);
}
foo.myApply({name: "jack"},18]);
Copy the code
Customize bind
Function.prototype.myBind = function(obj,... args1) {
return function(. args2) {
let key = Symbol("key");
obj[key] = this;
// Parameter collection process, function currization.
letresult = obj[key](... args1,args2);delete obj[key];
returnresult; }}function foo(name,age) {
console.log(this,name,age);
}
foo.bind({name:"abc"},"jack") (18);
Copy the code
Custom new
function myNew(fn,... args) {
let obj = {};
obj.__proto__ = fn.prototype;
letresult = fn.call(obj,... args);return typeof result === "object" ? result : obj;
}
function Person(name,age) {
this.name = name;
this.age = age;
}
let p = myNew(Person,"jack".18);
console.log(p);
Copy the code