账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    如何实现this指向不丢失问题
    • 2019-11-26 00:00
    • 10
    39
    0

    问题描述

    react 结合eventProxy, this.setState中的this指向为什么是正常的

    问题出现的环境背景及自己尝试过哪些方法

    个人觉得代码类似于下述:

    var obj = {
        name: 'dog',
        sayName() {
            console.log(this.name)
        }
    }
    
    var data = {
        name: 'cat',
        fn: obj.sayName
    }
    
    data.fn() // => cat

    相关代码

    // index.jsx
    import eventProxy from "./eventProxy";
    import React from "react";
    const Component = React.Component;
    
    class Parent extends Component {
      render() {
        return (
          <div>
            <Child_1 />
            <Child_2 />
          </div>
        );
      }
    }
    class Child_1 extends Component {
      componentDidMount() {
        setTimeout(() => {
          eventProxy.trigger("msg", "end");
        }, 1000);
      }
      render() {
        return <p>111</p>;
      }
    }
    class Child_2 extends Component {
      state = {
        msg: "start"
      };
    
      componentDidMount() {
        eventProxy.on("msg", msg => {
          // 如何保证了这里的this指向不丢失
          this.setState({
            msg
          });
        });
      }
    
      render() {
        return (
          <div>
            <p> child_2 component: {this.state.msg} </p>
            <Child_2_1 />
          </div>
        );
      }
    }
    class Child_2_1 extends Component {
      componentDidUpdate() {
        console.log("Child_2_1 update");
      }
    
      render() {
        return (
          <div>
            <p>child_2_1 component</p>
          </div>
        );
      }
    }
    export default Parent;
    // eventProxy.js
    const eventProxy = {
      onObj: {},
      oneObj: {},
      on: function (key, fn) {
        if (this.onObj[key] === undefined) {
          this.onObj[key] = [];
        }
    
        this.onObj[key].push(fn);
      },
      one: function (key, fn) {
        if (this.oneObj[key] === undefined) {
          this.oneObj[key] = [];
        }
    
        this.oneObj[key].push(fn);
      },
      off: function (key) {
        this.onObj[key] = [];
        this.oneObj[key] = [];
      },
      trigger: function () {
        let key, args;
        if (!arguments.length) return false
        key = arguments[0];
        args = [].concat(Array.prototype.slice.call(arguments, 1));
    
        if (this.onObj[key] !== undefined &&
          this.onObj[key].length > 0) {
          for (let i in this.onObj[key]) {
            this.onObj[key][i](args);
          }
        }
        if (this.oneObj[key] !== undefined &&
          this.oneObj[key].length > 0) {
          for (let i in this.oneObj[key]) {
            this.oneObj[key][i](args);
            this.oneObj[key][i] = undefined;
          }
          this.oneObj[key] = [];
        }
      }
    };
    export default eventProxy

    你期待的结果是什么?实际看到的错误信息又是什么?

    个人觉得this.setState中的this 应指向的是eventProxy.onObj.msg(type: array), 这里又没有setState方法,故应该会抛出“this.setState is not a function”的错误,
    但是结果却是正常执行

    希望哪位大佬指出我考虑不足之处或考虑错误之处,谢谢!!!

    补充v1.0.0

    执行阶段,eventProxy.obObj.msg 是一个数组,其实就是这样的一个对象

    {
        0:msg => { this.setState({msg})}
        // 省略其他属性
    }

    这种情况执行,即arr[0](), this 能指向原上下文?

    0
    打赏
    收藏
    点击回答
    您的回答被采纳后将获得:提问者悬赏的 10 元积分
        全部回答
    • 0
    • 很酷的小仙女 超级管理员 1楼

      在JavaScript中,this关键字可以用来引用当前作用域的变量或函数。但是,如果在函数中定义了一个内部函数或变量,这个内部函数或变量的this关键字默认指向全局对象。

      如果你想在函数中设置this指向某个特定的对象,你可以使用bind()函数或者call()函数。

      以下是使用bind()函数的例子:

      ```javascript function MyFunction() { this.myVariable = "Hello, world!"; }

      MyFunction.prototype.myMethod = function() { console.log(this.myVariable); };

      let myFunction = new MyFunction();

      myFunction.myMethod(); // 输出 "Hello, world!" ```

      以下是使用call()函数的例子:

      ```javascript function MyFunction() { this.myVariable = "Hello, world!"; }

      MyFunction.prototype.myMethod = function() { console.log(this.myVariable); };

      let myFunction = new MyFunction();

      myFunction.call(); // 输出 "Hello, world!" ```

      在这个例子中,bind()函数会创建一个新的函数,这个新的函数的this关键字会指向"MyFunction"对象,而不是全局对象。

      如果你想让myMethod方法中的this关键字始终指向"MyFunction"对象,你可以将MyFunction对象作为参数传递给myMethod方法:

      ```javascript let myFunction = new MyFunction();

      myFunction.myMethod(); // 输出 "Hello, world!" ```

      在这个例子中,myMethod方法中的this关键字始终指向"MyFunction"对象。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部