preface

The lunar calendar 2019 is coming to an end, taking advantage of a few days ago work things less, sorted out the basic knowledge of javascript, here to share with you, like the big guys can give a small praise. This article is also featured on Github.

I am making: github.com/Michael-lzg

JS Basic summary (1) – data types
JS Basic Summary (2) – prototype and prototype chain
JS Basics (3) – scope and closure
EventLoop — JS execution mechanism and EventLoop

This points to the

When developing in JavaScript, many developers are somewhat confused by the reference to this, but in fact, remember the most important thing about this reference: which object calls the function, and which object this refers to.

1. Ordinary functions: who calls to whom

The global variable points to the global object -window

var username = 'cn'
function fn() {
  alert(this.username) //cn
}
fu()
Copy the code

It is important to note that global variables declared by let do not refer to window objects

let username = 'cn'
function fn() {
  alert(this.username) //undefined
}
fn()
Copy the code

2. Object function calls

That’s the function call. Where does this point to

window.b = 2222
let obj = {
  a: 111.fn: function() {
    alert(this.a) / / 111
    alert(this.b) //undefined
  }
}
obj.fn()
Copy the code

3. Call from the constructor

A normal function in JS can use the new operator to create an object. In this case, the function is a constructor. The arrow function cannot be a constructor. When we execute the new operator, we do the following internally:

  1. Create an empty simple JavaScript object (that is {});
  2. Bind the constructor’s prototype to the new object’s prototype;
  3. Take the new object created in Step 1 as the context for this and execute the function;
  4. If the function does not return an object, this is returned.
function A () {
  this.a = 1
  this.func = () = > {
    return this}}let obj = new A()
console.log(obj.a) / / 1
console.log(obj.func() === obj) // true
Copy the code

4. Call in arrow function

The arrow function’s this points to the same context in which the arrow function is defined. For normal functions, this is determined when the function is called; For arrow functions, this is defined when the arrow function is defined and cannot be changed.

let obj = {
  A () {
    return () = > {
      return this
    }
  },
  B () {
    return function () {
      return this}}}let func = obj.A()
console.log(func() === obj) // true

func = obj.B()
console.log(func() === obj) // false
console.log(func() === window) // true
Copy the code

Apply, call, bind

In javascript, call and apply both exist to change the context in which a function is run; in other words, to change the reference to this within the function body. For example

function fruits() {}

fruits.prototype = {
  color: 'red'.say: function() {
    console.log('My color is ' + this.color)
  }
}

var apple = new fruits()
apple.say() //My color is red

// But if we have an object banana= {color: "yellow"} and we don't want to redefine the say method for it,
// Then we can use Apple's say method with call or apply:
banana = {
  color: 'yellow'
}
apple.say.call(banana) //My color is yellow
apple.say.apply(banana) //My color is yellow
Copy the code

Apply and call are different

For apply and Call, the effect is exactly the same, except that the way parameters are accepted is different

func.call(this, arg1, arg2)
func.apply(this, [arg1, arg2])
Copy the code

Apply, call instances

// Array append
var array1 = [12 , "foo" , {name:"Joe"}, -2458];
var array2 = ["Doe" , 555 , 100];
Array.prototype.push.apply(array1, array2);
// array1 values [12, "foo", {name:"Joe"}, -2458, "Doe", 555, 100]

// Get the maximum and minimum values in the array
var  numbers = [5.458 , 120 , -215 ];
var maxInNumbers = Math.max.apply(Math, numbers),   / / 458
var maxInNumbers = Math.max.call(Math.5.458 , 120 , -215); / / 458

// Verify that it is an array
functionisArray(obj){
  return Object.prototype.toString.call(obj) === '[object Array]'
}
Copy the code

bind()

The simplest use of bind() is to create a function that has the same value no matter how it is called. The bind() method creates a new function, called the bind function, which, when called, takes as this the first argument passed to the bind() method when it was created, The second and subsequent arguments passed to the bind() method are called as arguments to the original function, along with arguments from the bind function’s runtime itself, in that order.

this.num = 9
var mymodule = {
  num: 81.getNum: function() {
    console.log(this.num)
  }
}

mymodule.getNum() / / 81

var getNum = mymodule.getNum
getNum() // 9, because in this case, "this" refers to the global object

var boundGetNum = getNum.bind(mymodule)
boundGetNum() / / 81
Copy the code

When you call bind, the first argument to bind is the value referred to by this in the function’s scope

function func() {
  console.log(this)}let newFunc = func.bind({ a: 1 })
newFunc() // Print: {a:1}

let newFunc2 = func.bind([1.2.3])
newFunc2() // print: [1,2,3]

let newFunc3 = func.bind(1)
newFunc3() // Print: Number:{1}

let newFunc4 = func.bind(undefined / null)
newFunc4() // Print: window
Copy the code
  • When passed null or undefined, this points to window in non-strict mode.
  • When a simple value is passed in, it is internally wrapped into an object of the corresponding type. The Number method is called to wrap the Number. A String is wrapped with a String method; True /false calls the Boolean method wrapper. To get the original value, call the valueOf method.

The order in which arguments are passed

function func(a, b, c) {
  console.log(a, b, c) // Prints the arguments passed in
}

let newFunc = func.bind({}, 1.2)

newFunc(3) / / 1, 2, 3
// As you can see, arguments passed in bind are passed to the original function first.
Copy the code

The new function returned is treated as a constructor

/ / function
function func(name) {
  console.log(this) // Print: through {name:'wy'}
  this.name = name
}
func.prototype.hello = function() {
  console.log(this.name)
}
let obj = { a: 1 }
// Call bind to return the new function
let newFunc = func.bind(obj)

// Use the new function as a constructor to create an instance

let o = new newFunc('seven')

console.log(o.hello()) // Print: 'seven'
console.log(obj) // Print: {a:1}
Copy the code

Instead of referring to the first argument passed to bind, this in func points to the instance created with new. You can find the method on the func prototype while using instance O to find the method hello on the prototype.

Compare apply, call, and bind

  • Apply, call, and bind are all used to redirect the function’s this object.
  • The first argument to apply, call, and bind is the object to which this refers.
  • Apply, call, and bind can all pass arguments using subsequent parameters.
  • Bind returns the corresponding function for later call; Apply and call are immediate calls.
var obj = {
  x: 81
}

var foo = {
  getX: function() {
    return this.x
  }
}

console.log(foo.getX.bind(obj)()) / / 81
console.log(foo.getX.call(obj)) / / 81
console.log(foo.getX.apply(obj)) / / 81
Copy the code

Recommend the article

Build a WebPack project from scratch
Summary of several webpack optimization methods
Summarize the methods of front-end performance optimization
Several common JS recursive algorithms
Build a VUE-CLI mobile TERMINAL H5 development template
Encapsulate a TOAST and Dialog component and publish it to NPM
This article covers front-end routing, back-end routing, single-page application, multi-page application
About several mobile terminal soft keyboard pit and its solution
Discussion on JavaScript anti – shake and throttling