The title

  • How to value this in different application scenarios?

    • As a general function
    • Use call Apply bind
    • Called as an object method
    • Called in the class method
    • Arrow function
    • (The value of this is checked when the function is executed, not when the function is defined)
  • Handwritten bind

  • The application scenarios of closures in actual development are illustrated with examples

Scenario questions

// Create 10 '' tags and pop up the corresponding serial number when clicked
let i ,a;
for(i = 0; i < 10; i++){
    a = document.createElement('a');
    a.innerHTML = i + '<br>';
    a.addEventListener('click'.function(e){
        e.preventDefault();
        alert(i);
    })
    document.body.appendChild(a)    
}
Copy the code

knowledge

  • Scope and free variables
    • Global scope, function scope, block office scope (new in ES6)
  • closure
  • this

Scope and free variables

//ES6 block level scope
if(true) {let x = 100
}
console.log(x) / / complains
Copy the code

Free variables

  • A variable is not defined in the current scope, but is used
  • Search through the upper scope, layer by layer, until you find it
  • If the global scope is not found, xx is not defined

closure

Closure: The search for free variables is done where the function is defined, in the parent scope, not where it is executed!

// function as return value
function create(){
    let a = 100
    return function(){
        console.log(a)
    }
}
let fn = create()
let a = 200
fn() / / 100
Copy the code
// function as argument
function print(fn){
    let a = 200
    fn()
}
let a = 100
function fn(){
    console.log(a)
}
print(fn) / / 100
Copy the code

this

  • As a general function
  • Use call Apply bind
  • Called as an object method
  • Called in the class method
  • Arrow function

What value does this take when the function is executed, but not when the function is defined

function fn1(){
    console.log(this)
} 
fn1() //window

fn1.call({x:100}) //{x:100}

const fn2 = fn1.bind({x:200})
fn2() //{x:200}
Copy the code
const zhangsan = {
    name:'zs'.sayHi(){
        // This is the current object
        console.log(this)},wait(){
        setTimeout(function(){
            //this === window 
            console.log(this)}}}const lili = {
    name:'lili'.sayHi(){
        // This is the current object
        console.log(this)},waitAgain(){
        setTimeout(() = >{
            // This is the current object
            console.log(this)}}}Copy the code
class People{
    constructor(name){
        this.name = name,
        this.age = 20
    }
    sayHi(){
        console.log(this)}}const zhangsan = new People('Joe')
zhangsan.sayHi() / / zhangsan object
Copy the code

Handwritten bind

Bind basic usage

function fn1(a,b,c){
    console.log(this),
    console.log(a , b , c);
    return 'this is fn1';
}

const fn2 = fn1.bind({x:100},10.20.30);
const res = fn2();
console.log(res);
/ / print:
//{x:100}
/ / 10 20 to 30
//this is fn1
Copy the code

Write a bind

The bind / / simulation
Function.prototype.bind1 = function(){
    // Split the parameters into arrays
    const args = Array.prototype.slice.call(arguments)
    // Get this (first item of array)
    const _this = args.shift();
    //fn1.bind(...) The fn1
    const self = this;
    // Return a function
    return function(){
        return self.apply(_this,args)
    }
}

function fn1(a,b,c){
    console.log(this),
    console.log(a , b , c);
    return 'this is fn1';
}

const fn2 = fn1.bind1({x:100},10.20.30);
const res = fn2();
console.log(res);
/ / print:
//{x:100}
/ / 10 20 to 30
//this is fn1
Copy the code