如何处理fn.call(this)替换原来的this

时间:2018-08-08 23:18:48

标签: javascript

首先,我有一个用于管理员工的应用程序。当用户创建应用程序的新实例时,我希望他们可以选择提交一个功能,该功能将在应用程序中的其他任何功能之前运行。问题是我需要在该功能的末尾添加功能,因此我需要将其传递回应用程序。

但是,如果我在fn.call(this)类中使用StateManager.js,则它将覆盖状态管理器的this并摆脱了StateManager的功能。返回的确切错误是Uncaught TypeError: this.onPreload is not a function

基本上,当创建一个新实例时,我想使用用户的preload函数并将其传递给StateManager.js进行调整。

这是演示代码:

class Application {

  constructor(options = {}) {
    return new User(options);
  }
}

class User {

  constructor(options) {
    this._options = options;
    this.state = new StateManager(this);
    this.job = new Job(this);
    this.init();
  }

  init() {
    this.state.onPreload = this._options.preload;
    this.state.preload.call(this);
  }
}

class Job {

  constructor(user) {
    this.user = user;
  }

  changeTitle(title) {
    this.user.jobTitle = title;
  }
}

class StateManager {

  constructor(user) {
    this.user = user;
    this.onPreload = null;
  }

  preload() {
    this.onPreload();
  }
}

const options = {
  preload: preload
};

const app = new Application(options);

function preload() {
  app.job.changeTitle('CEO');
}

index.js

import { Application } from './Application.js';

const options = {
    preload: preload
};

const app = new Application(options);

function preload() {
    // Access some irrelevant function in job that sets a new value
    app.job.changeTitle('CEO');
}

app.js

import { User } from './User.js';

export class Application {
    constructor(options = {}) {
        return new User(options);
    }
}

user.js

import { StateManager } from './StateManager.js';
import { Job } from './Job.js';

export class User {
    constructor(options = {}) {
        this._options = options;
        this.state = new StateManager(this);
        this.job = new Job(this);

        this.init();
    }

    init() {
        this.state.onPreload = this._options.preload;
        this.state.preload.call(this);
    }
}

statemanager.js

export class StateManager {
    constructor(user) {
        this.user = user;
        this.onPreload = null;
    }

    preload() {
        this.onPreload();

        // My custom functionality to add at the end.
    }
}

1 个答案:

答案 0 :(得分:1)

y = 1指的是全局变量preload(),但首先是在用于初始化app的函数中调用它的。它需要接收正在初始化的app对象,而不是引用全局变量。

使用Userthis.state.onPreload = this._options.preload.bind(this);函数的上下文绑定到该对象。

您也可以将preload更改为使用StateManager.preload()。但这可能会导致不适当地的依赖关系,并不能在所有情况下都适用。如果我更好地理解了所有关系,那么也许可以更好地做出决定。

this.onPreload.call(this.user);