Focus onThe front small OuTo read more original technical articles

Related code →

10.9 Inside a function

  • There are two special objects inside functions in ES5argumentsthis, 1 internal attributecaller
  • ES6 newnew.targetattribute

10.9.1 the arguments

  • argumentsIs aAn array of classObject that contains everything passed in when the function is calledparameter
  • Only tofuncitonKeyword is available when defining a functionargumentsObject (The arrow function is not there)
  • Object has acalleeAttribute, pointing toargumentsPointer to the function(Note: Pointers are function names, not functions.)
    • In strict mode, accessarguments.calleecomplains
// Recursive function: calculates factorial
function factorial(num) {
  if (num <= 1) return 1
  else return num * factorial(num - 1)}// Use arguments.callee to decouple function logic from function names
function factorial(num) {
  if (num <= 1) return 1
  else return num * arguments.callee(num - 1) // Callee points to the function where arguments objects reside
}

let trueFactorial = factorial // Save the pointer to the function

Overwrite factorial with the trueFactorial pointer unchanged
factorial = function () {
  return 0
}
console.log(trueFactorial(5)) // 120, the function body code is uncoupled with the function name using arguments.callee, and the calculation is still normal
console.log(factorial(5)) // 0, the function has been rewritten
Copy the code

10.9.2 this

  • inStandard functions,thisPoint to theThe context object of the calling function, i.e.,The environment object in which the function executes(Global scope points towindow)
window.color = 'red' // vscode is the node runtime environment and cannot recognize the global object window
let o = { color: 'blue' }
function sayColor() {
  console.log(this.color)
}
sayColor() // 'red', this points to a global object
o.sayColor = sayColor
o.sayColor() // 'blue', this refers to object o
Copy the code
  • inArrow function,thisPoint to theDefines the context object for the function, i.e.,The environment object outside the function
let sayColor2 = () = > {
  console.log(this.color) // this refers to the context in which sayColor2 is defined, i.e. the global object
}
sayColor2() // 'red', this points to a global object
o.sayColor2 = sayColor2
o.sayColor2() // 'red', this points to a global object
Copy the code
  • inEvent callbackorTimer callbackWhen a function is called inthisPoint to theIs notThe callback function is written asArrow functionSolvable problem
function King() {
  this.royaltyName = 'Henry'
  setTimeout(() = > {
    console.log(this.royaltyName) // The arrow function, this refers to the context in which the function is defined, i.e. the function context of King()
  }, 1000)}function Queen() {
  this.royaltyName = 'Elizabeth'
  setTimeout(function () {
    console.log(this.royaltyName) // For the standard function, this refers to the context in which the function was called, i.e. the context of setTimeout()
  }, 1000)}new King() // 'Henry', 1 second to print
new Queen() // use undefined to print after 1 second
Copy the code

10.9.3 caller

  • ES5 definescallerAttribute, pointing toA function that calls the current function(Null in global scope)
function callerTest() {
  console.log(callerTest.caller)
}
callerTest() // Null, called in the global scope

function outer() {
  inner()
}
function inner() {
  console.log(inner.caller)
}
outer() // [Function: outer], called on outer()

// Decouple
function inner() {
  console.log(arguments.callee.caller) // arguments.callee points to a pointer to the function where Arguments is located, i.e. the inner
}
outer() // [Function: outer], called on outer()
Copy the code
  • arguments.callerThe value of is alwaysundefinedThis is to distinguisharguments.callerAnd the function ofcaller
  • In strict mode, an error will be reported when you access arguments.caller and assign a value to the function’s Caller attribute
function inner2() {
  console.log(arguments.caller) // undefined
  console.log(arguments.callee) // [Function: inner2]
}
inner2()
Copy the code

10.9.4 new.target

  • ES6 adds inside functionsnew.targetProperties, detection functionsWhether to usenewKeyword
    • Don’t usenewThe call,new.targetThe value isundefined
    • usenewThe call,new.targetThe value isThe constructor that is called
function King2() {
  if (!new.target) {
    console.log(new.target, 'King2 must be instantiated using "new"')}else {
    console.log(new.target, 'King2 instantiated using "new"')}}new King2() // [Function: King2] 'King2 instantiated using "new"'
King2() // undefined 'King2 must be instantiated using "new"'
Copy the code

10.10 Function Properties and Methods

  • The function contains two properties: Length and Prototype

    • lengthSave what the function wants to receiveNumber of named parameters
    function nameLength(name) {
      return name
    }
    function sumLength(sum1, sum2) {
      return sum1 + sum2
    }
    function helloLength() {
      return 'Hello'
    }
    console.log(nameLength.length, sumLength.length, helloLength.length) / / 1 2 0
    Copy the code
    • prototypePoints to the function’s prototype object, saving the functionAll instance methodsandAn enumeration(using thefor-inCannot be found)
    console.log(Array.prototype) // View the Array prototype object in the browser, including methods such as sort()
    console.log(Object.keys(Array)) // [], all enumerable properties of the Array constructor itself
    console.log(Object.getOwnPropertyNames(Array)) // ['length', 'name', 'prototype', 'isArray', 'from', 'of']
    Copy the code
  • The function has three methods: apply(), call(), and bind()

    function sumPrototype(num1, num2) {
      return num1 + num2
    }
    Copy the code
    • apply()andcall()Will be specifiedthisValue calls a function, i.eSet up theThe body of a function when it is calledthisthePoint to the
    • apply()It takes two arguments: ① The scope of the run function (specifying this); ② Array of arguments (instances or Arguments objects are available)
    function applySum1(num1, num2) {
      return sum.apply(this.arguments) // Pass the arguments object
    }
    function applySum2(num1, num2) {
      return sum.apply(this, [num1, num2]) // Pass in the array instance
    }
    console.log(applySum1(10.10)) / / 20
    console.log(applySum2(10.10)) / / 20
    Copy the code
    • call()Take several arguments: ① The scope of the run function (specifying this); The rest of the parameters are passed in one by one
    function callSum(num1, num2) {
      return sum.call(this, num1, num2) // Pass each parameter one at a time
    }
    console.log(callSum(10.10)) / / 20
    Copy the code
    • apply()call()Here’s what’s really powerfulThe ability to extend the scope in which functions run, i.e.,Control function bodythisvalue
    window.color = 'red' // vscode is the node runtime environment and cannot recognize the global object window
    let o2 = { color: 'blue' }
    function sayColor3() {
      console.log(this.color)
    }
    sayColor3() // 'red', this points to a global object
    sayColor3.call(this) // 'red', this points to a global object
    sayColor3.call(window) // 'red', this points to the global object, test to change window to global
    sayColor3.call(o2) // 'blue', this refers to the object O2
    Copy the code
    • Function.prototype.apply.call(), the function prototypeapplyMethods usingcall()To bind the vm to the vmReflect.apply()Simplified code)
    let f1 = function () {
      console.log(arguments[0] + this.mark)
    }
    let o3 = {
      mark: 95,
    }
    f1([15]) // '15undefined', this refers to the function context of f1, this.mark is undefined
    f1.apply(o3, [15]) // 110, bind this of F1 to O3
    Function.prototype.apply.call(f1, o3, [15]) // 110, the apply method of the prototype object of function f1, binding with call
    Reflect.apply(f1, o3, [15]) // 110, initiates the call to the target function with the specified argument list, three arguments (the target function, the bound this object, and the argument list)
    Copy the code
    • bind()Create a new function instance whosethisbeThe bindingtoTo pass tobind()The object of
    let o4 = { color: 'blue' }
    function sayColor4() {
      console.log(this.color)
    }
    let bindSayColor = sayColor4.bind(o4) // Create an instance of bindSayColor with this bound to o4
    sayColor4() // 'red', this points to a global object
    bindSayColor() // 'blue', this is bound to object o4
    Copy the code

10.11 Function expressions

  • The key feature of function declarations is function declaration promotion, in which function declarations are defined before the code is executed
sayHi() // 'Hi', call first and declare later
function sayHi() {
  console.log('Hi')}Copy the code
  • Function expressionMust beFirst assign, then useWhich creates a ** anonymous function (function** and then assign it to a variable
    • Anonymous functionnameProperty is an empty string
sayHi2() // ReferenceError: Cannot access 'sayHi2' before initialization
let sayHi2 = function sayHi() {
  console.log('Hi')}Copy the code
  • The difference between function declarations and function expressions is promotion. In conditional blocks, function declarations can be avoided and function expressions can be used
let condition = false
if (condition) {
  function sayHi3() {
    console.log('true')}}else {
  function sayHi3() {
    console.log('false')
  }
}
sayHi3() // The result varies by browser. Avoid using function declarations in conditional blocks

let sayHi4
if (condition) {
  sayHi4 = function () {
    console.log('true')}}else {
  sayHi4 = function () {
    console.log('false')
  }
}
sayHi4() // false, you can use a function expression in a conditional block
Copy the code
  • Creating functions and assigning values to variables can be used to return another function as a value within a function
/** * Sort an array by an object key *@param {String} Key Key star to be sorted@param {String} Sort Forward/reverse order: ASC/DESC. The default value is ASC */
function arraySort(key, sort) {
  return function (a, b) {
    if (sort === 'asc' || sort === undefined || sort === ' ') {
      A [key] > b[key]
      if (a[key] > b[key]) return 1
      else if (a[key] < b[key]) return -1
      else return 0
    } else if (sort === 'desc') {
      A [key] < b[key]
      if (a[key] < b[key]) return 1
      else if (a[key] > b[key]) return -1
      else return 0}}}var userList = [
  { name: 'Tony'.id: 3 },
  { name: 'Tom'.id: 2 },
  { name: 'Jack'.id: 5},]console.log(userList.sort(arraySort('id'))) / / [{name: "Tom, id: 2}, {name:" Tony ", id: 3}, {name: "Jack", id: 5}], sorted by id positive sequence
console.log(userList.sort(arraySort('id'.'desc'))) / / [{name: "Jack", id: 5}, {name: "Tony", id: 3}, {name: 'Tom', id: 2}], according to the id arranged in reverse chronological order
console.log(userList.sort(arraySort('name'))) / / [{name: "Jack", id: 5}, {name: 'Tom', id: 2}, {name: "Tony", id: 3}], according to the name positive sequence alignment
Copy the code

Summary & ask points

  • What is arguments? Where does arguments.callee point to? Write code that represents a factorial function whose name is logically decoupled from the function
  • What’s the difference between this in the standard function and the arrow function? Why is the arrow function better suited for event or timed callbacks?
  • Where does the function’s Caller attribute point to? What is the value of the caller? What are the restrictions on the Caller in strict mode?
  • What is the function and value of new.target?
  • What properties does a function have? What are its directions and usages?
  • Please use the code to prove the apply (), call (), bind () is how to expand the Function scope, and explains the Function, the prototype. Apply. The meaning of the call ()
  • What is the biggest difference between a function declaration and a function expression? How to understand the declaration of ascension?
  • Write a piece of code to sort according to an object property in an object array. The sort property and ascending/descending order can be determined according to the parameters