
前言
整理一下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>);
}
}
注: 如果你写的是通用组件,推荐第一种方式,这涉及原型的相关内容,暂且不表。
最后
谢谢阅读,如有谬误,恳请斧正。