前言
整理一下javascript
(包括ES3
、ES5
、ES6
)中的this
问题。
ECMAScript 3/5
这个版本的this
很明确,只有以下五种情况:
全局
console.log(this); // this 等于 ECMAScript 在浏览器环境的 Global 对象,即 window
复制代码
函数内
function foo() {
console.log(this); // this 还是 window
}
复制代码
方法调用
var obj = {
name: 'alex',
getName: function(){
console.log(this.name);
}
}
obj.getName(); // this 为 obj
var bar = obj.getName;
bar(); // 用这种方式调用,this 就指向了 window,因为这样调用时,函数的执行环境是全局的
复制代码
构造函数
function Foo() {}
Foo.prototype.getName = function(){
console.log(this.name);
}
var bar = new Foo();
bar.name = 'alex';
bar.getName(); // this 指向实例 bar
复制代码
显示调用
apply
和call
改变函数运行时的this
指向
function foo(){
console.log(this.name);
}
var applyObj = {
name: 'alex'
}
var callObj = {
name: 'f0rest'
}
foo.apply(applyObj); // alex
foo.call(callObj); // f0rest
复制代码
ECMAScript 6
在ES 6
,我们大部分函数的写法都是使用箭头函数(arrow function
),它的this
不同于ES 5
。
箭头函数
// ES 5
var foo = function(options){ console.log('alex'); };
// ES 6
const foo = (options) => { console.log('alex'); };
// ES6 function to return a object
const foo = () => ({ name: 'f0rest' });
复制代码
ES 6
中的规则是,紧随箭头的{
被解析为块的开始,而不是对象的开始,所以小括号包裹对象字面量是唯一一个你需要牢记的小窍门
this
箭头函数它没有自己的this
值,它继承外围作用域的this
下面这个例子,this
为undefined
,因为ES 6
是严格模式,严格模式下全局作用域的this
为undefined
const foo = (options) => {
console.log(this); // undefined
};
复制代码
在React
中的实践
在React
组件中,注册事件有三种方式,目的是让事件函数内的this
指向这个当前组件实例
我们用
ES 6
的语法来进行react
应用开发
方法1
在constructor
方法中绑定
class App extends React.Component {
constructor() {
this.myEvent = this.myEvent.bind(this);
}
myEvent() {
console.log(this);
}
render() {
return (<div onClick={this.myEvent}>demo</div>);
}
}
复制代码
方法2
在render
方法中绑定,因为render
方法已经为你绑定了this
class App extends React.Component {
myEvent() {
console.log(this);
}
render() {
return (<div onClick={this.myEvent.bind(this)}>demo</div>);
}
}
复制代码
方法3
这里就是箭头函数,继承外围作用域的 this,即当前组件实例
class App extends React.Component {
myEvent = () => {
console.log(this);
}
render() {
return (<div onClick={this.myEvent}>demo</div>);
}
}
复制代码
注: 如果你写的是通用组件,推荐第一种方式,这涉及原型的相关内容,暂且不表。
最后
谢谢阅读,如有谬误,恳请斧正。