首先来看下类中定义的原型方法的this不同调用时的指向:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script type="text/javascript">
class Person{
constructor(){
console.log("Person类constructor中的this:");
console.log(this);
}
speak(){
console.log("Person类speak方法中的this:");
console.log(this);
}
}
const person1 = new Person(); // this:Person{}
person1.speak(); // this:Person{}
const s = person1.speak;
s(); // this: undefined
// 此处如果window.s()会报s不存在
</script>
</body>
</html>
事件调用方法时方法中的this指向:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<Button onclick="hanleClick()">this指向</Button>
<script type="text/javascript">
function hanleClick(){
console.log("this指向:");
console.log(this);
}
// 当点击Button时,hanleClick中的this指向为window
</script>
</body>
</html>
类中的方法默认开启了局部的严格模式,严格模式下this为undefined:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<Button onclick="hanleClick()">this指向</Button>
<script type="text/javascript">
function hanleClick(){
"use strict"
console.log("this指向:");
console.log(this);
}
// 开启严格模式前:当点击Button时,hanleClick中的this指向为window
// 开启严格模式后:当点击Button时,hanleClick中的this指向为undefined
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
class MyComponent extends React.Component{
// 1、handleClick放在哪?MyComponent原型上,供MyComponent实例调用;
// 2、handleClick是作为onClick的回调,所以不是通过实例调用的,是直接调用;
// 3、类中的方法默认开启了局部的严格模式,严格模式下this为undefined(这个和Babel没关系)
handleClick(){
console.log("React类的自定义方法中的this为:");
console.log(this); // 当点击h2标签时,this为undefined
}
render(){
return <h2 onClick={this.handleClick}>我是类定义的组件</h2>;
}
}
ReactDOM.render(<MyComponent/>, document.getElementById("app"));
</script>
</body>
</html>
如何让自定义原型方法中的this指向为组件实例?
一、在constructor中bind绑定组件的this:
class Button extends React.Component{
constructor(pops){
super();
this.handleClick = this.handleClick.bind(this); // 将原型方法handleClick的this指向为实例对象,然后赋给实例方法handleClick,此时实例上和原型上都有handleClick方法
}
handleClick = () => {
console.log("this is ", this);
}
render(){
return (<button onClick={this.handleClick}>按钮</button>)
}
}
二、方法使用时绑定 this:
class Button extends React.Component{
constructor(props){
super(props);
}
handleClick = () => {
console.log("this is ", this);
}
render(){
return (<button onClick={this.handleClick.bind(this)}>按钮</button>)
}
}
ReactDOM.render(
<Button/>,
document.getElementById("app")
);
三、使用属性初始化语法:
class LoggingButton extends React.Component {
// 这个语法确保了 `this` 绑定在 handleClick 中
// 这里只是一个测试
handleClick = () => {
console.log('this is:', this);
}
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
四、在回调函数中使用 箭头函数:
class LoggingButton extends React.Component {
handleClick() {
console.log('this is:', this);
}
render() {
// 这个语法确保了 `this` 绑定在 handleClick 中
return (
<button onClick={(e) => this.handleClick(e)}>
Click me
</button>
);
}
}
五、函数传参:
<button onClick={this.函数名.bind(this, '我是参数')}>点我传递实参</button>
fune(x, e){
...
}
...
render(){
return (<button onClick={e => {this.fune("我是实参", e)}}>点我传递实参</button>)
}