JavaScript中改变context上下文的方法


序言:

        作为一名合格的前端开发者,大家都应该知道改变js作用域中上下文的方法有:call、apply和bind。思考一个问题:还有没有更好的实现方式呢?

1、call和apply

call和apply是最简单实现改变函数体内部this指向的方法,他们的区别仅仅是第二个参数不同。语法示例:

obj.call(thisObj,arg1,agr2,...)
obj.apply(thisObj,[arg1,agr2])

代码示例(Math.max)

Math.max(1, 3, 2)

 如输入参数是数组呢?

Math.max.apply(null,[1,2,3,4,2,3])

说明:上面示例代码中,第一个参数为null,也可以为其他(空字符串,对象),仅仅是“借用”Math的max方法而已。

2、bind

bind方法是创建一个新方法,当函数调用时将this设置为提供的值。与call类似,除第一个参数外是可变参数,语法示例:

obj.bind(thisObj,arg1,agr2,...)

这时thisObj就有了obj方法和属性。

bind与call和apply不同的是,bind之后返回一个函数,不会立即执行。需要再显示执行一次才能完成函数的调用。如:

let m = test.bind(obj,3) m()

另外,bind也常用在ES6的Class绑定上下文。

class Dog { constructor() { this.name = 'adong'; } start() { this.p().then(this.say); } p() { return new Promise((resolve, reject)=>{ resolve('good'); }) } say(str) { console.log(this); console.log(this.name + str); } } let dog = new Dog(); dog.start();

上述代码会显示:

 

 即在Promise的then方法参数是一个匿名函数,匿名函数的this指向是:undefined。

这里有2种方案:

(1)箭头函数

class Dog { constructor() { this.name = 'adong'; } start() { this.p().then(this.say); } p() { return new Promise((resolve, reject)=>{ resolve('good'); }) } say= (str) => { console.log(this); console.log(this.name + str); } } let dog = new Dog(); dog.start();

 

 即,使用箭头函数,this执行函数定义时作用域,即Dog对象

(2)使用bind绑定this指向

class Dog { constructor() { this.name = 'adong'; } start() { this.p().then(this.say.bind(this)); } p() { return new Promise((resolve, reject)=>{ resolve('good'); }) } say(str) { console.log(this); console.log(this.name + str); } } let dog = new Dog(); dog.start();

3、使用ES7的Decorators

使用autobind-decorator库,实现自动this绑定。

import autobind from 'autobind-decorator' class MathTest { constructor(val) { this.val = val } @autobind show() { return this.val } } let mathTest = new mathTest(42); let show = mathTest.show; show()

 当然@autobind也可以在整个类上进行this上下文的绑定。

4、双冒号运算符

双冒号左边是一个对象,右边是一个函数。该运算符会自动将左边的对象,作为上下文环境(即this对象),绑定到右边的函数上面。

示例代码:

[1,2,3]::Array.prototype.map(x=>{return x*3})

经过babel编译后:

"use strict"; var _context; (_context = [1, 2, 3], Array.prototype.map).call(_context, function (x) { return x * 3; });

即对象[1,2,3]作为this绑定到了Array的map方法上。

5、总结

以上即是js中绑定this上下文的方法,助力源码阅读。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM