this routine function and the function of the arrow binding problem

The core elements

function () {} and () => {} The biggest difference is that the former will be bound at run time this object, the latter is not

Since the function () {} at runtime automatically bound inside this object, this does not access the external scope
since () => {} is not automatically bound this object, this can only access the external scope

To use this dynamic binding, use the function () {}
To use this external scope, using () => {}

ES6 estimate because function () {} always automatically bound to this cause needs to let self = this nested function, then need to use self.xxx call this outer layer in the inner layer function, it does not automatically add a new tie given this function: the function of the arrow () => {}

function () {} rules of this binding

function () {} at runtime (it is invoked) for dynamically binding rules based on this binding

There are two points to emphasize:

  • this is bound at run time, when not defined
  • Look at this point, the key is to look at where and how the function calls

Depending on the location and function calls the way, there are four binding policy

1. default binding
if direct call function, then this is bound to the global object is global in Node, the window is in the browser

function foo () {
    console.log(this)
}

// 运行时绑定
foo()

2. implicit binding
if there is a context object to call a function, then this is bound to the context object

const obj = {
    foo: function () {
        console.log(this)
    }
}

// 运行时绑定
obj.foo()

3. The explicit binding
to bind by calling the function call, apply, bind method

function foo () {
    console.log(this);
}
const obj = { a: 1 }

// 运行时绑定
foo.call(obj)
foo.apply(obj)
foo.bind(obj)()

4.new binding
process is new, also known as "constructor call" function, through the following steps:
1. Create an empty object obj
2. associate to object obj Prototype Prototype constructor
3. bind objects to this constructor
4. If a constructor does not return the object, the object obj returns

function Foo () {
    console.log(this);
}

// 运行时绑定
foo = new Foo()

Common scenarios induction

1. Method Object Definition: using function () {} to obtain this bound
2. Scene callback function: using () => {} to access this external scope

const dog = {
    name: "旺仔",
    eat: function (callback) {
        // 这里的this采用隐式绑定策略
        // 因为调用方式是this.eat() (run和sleep方法中)
        setTimeout(() => {
            console.log(`${this.name}吃饱了`)
            callback()
        }, 3000);
    },
    run: function () {
        // 这里的this无法进行绑定,只能从外层作用域获得,在这里指向最外层(模块级别)this
        // 在node中模块级别this指向module.exports
        // node是模块化的,模块本身存在独立作用域,要和浏览器的全局概念区分
        this.eat(() => {
            console.log(`${this.name}开始跑步`);
        })
    },
    sleep: function () {
        // 这里的this采用默认绑定策略
        // 因为调用方式是callback() (eat方法中)
        this.eat(function () {
            console.log(`${this.name}准备睡觉`);
        })
    }
}

dog.run()
// 旺仔吃饱了
// 旺仔开始跑步
dog.sleep()
// 旺仔吃饱了
// undefined准备睡觉

3. The event listener scene: use function () {} to get this bind

// 事件监听器调用仍然是上下文调用,socket.handle()
socket.on('data', function handle () {
    console.log(this)
})

Guess you like

Origin www.cnblogs.com/Peter2014/p/12168456.html