如何在同一文件中调用Javascript方法?

问题描述 投票:2回答:3

我有这样的代码:

mycode.js:

export default {
  foo() {
    return "foo";
  },
  bar() {
    return "bar" + this.foo();
  }
}

othercode.js:

import mycode from "mycode.js";

mycode.bar();  // usually works fine, returns "barfoo"

但是,我在箭头函数内调用mycode.bar()时遇到了困难。问题是bar()中的“ this”不再引用mycode中的对象,而是引用调用者的上下文。

如果我想继续使用此代码样式来定义函数并导出它们,如何在bar()中调用foo()?

我已经尝试将mycode中的方法绑定()到导出的对象,但是据我所知,您必须对每个方法分别进行此操作。

我也在mycode的顶部尝试这样做:

let self = this;

然后引用“ self.foo()”,但是在我将其分配给self时尚未定义“ this”。

我可以完全更改代码样式。我可以这样定义每个函数:

mycode.js

function foo() {
  return "foo";
}

export default {
  foo, bar, ...
}

但是我必须分别命名每个功能。

必须有更好的方法。

javascript
3个回答
1
投票

问题不在于您如何导出;这是this在JavaScript中的工作方式。如果在作为方法的上下文之外引用函数,则该方法的主体将没有一致的this,除非您明确绑定了该函数,并且除非有标识符绑定到该对象,否则您将无法进行任何绑定。您可以这样做,例如:

const mod = {
  foo() {
    return "foo";
  },
  bar() {
    return "bar" + this.foo();
  }
};

mod.foo = mod.foo.bind(mod);
mod.bar = mod.bar.bind(mod);

export default mod;

...但是,我敢肯定,这简明扼要。如果使用类和支持类属性的JS版本,则另一种选择是:

class MyModule {
  foo: () => "foo";
  bar: () => "bar" + this.foo();
}

export default new MyModule();

个人,虽然我不了解您的整体情况,但我认为命名导出更有意义,并使用模块闭包代替this

export function foo() {
  return "foo";
}

export function bar() {
  return "bar" + foo();
}

1
投票

如果使用命名的导出而不是默认的导出,则可以引用要导出的对象的名称,例如:

export const myMethods = {
  foo() {
    return "foo";
  },
  bar: () => {
    return "bar" + myMethods.foo();
  }
};

请确保也将导入更改为命名导入:

import { myMethods } from 'mycode.js';

can also导入当前模块(感谢Bergi),尽管看起来非常奇怪:

import myMethods from './mycode.js'; // <--- THE CURRENT FILE
export default {
  foo() {
    return "foo";
  },
  bar: () => {
    return "bar" + myMethods.foo();
  }
}

默认导出的最大问题之一是,除非像上面那样导入当前模块,否则无法引用要导出的内容。如果您使用默认的export and函数是一个箭头函数,则this将从模块的外部范围继承,因此要导出的对象必须经过奇怪的引用才能被引用如上。


1
投票

您可以表达或声明您的功能,在文件中内部使用,然后决定将哪些功能制成public(出口)。

命名的导入

由于使用通配符,您可以获得更大的有效负载并添加了不需要的保密层,因此您最好始终命名要导入的所需方法

通过使用[{named}导入列表,不再有as <alias>指针,使得this结果出现在undefined

PS:导出属性时为get rid of the default

default

使用表达式 命名进口

// foo.mjs

function foo() {
  return "foo";
}

function bar() {
  console.log(this);    // undefined 
  return "bar" + foo();
}

export {
  foo,
  bar
}

运行// index.mjs import { bar } from './foo.mjs'; console.log(bar()); // "barfoo" ,您将在日志$ node --experimental-modules ./index.mjs中看到


通配符导入"barfoo"

Careful:通配符导入会将* as alias引用为常数this alias导入as

[Module]
// foo.mjs

function foo() {
  return "foo";
}

function bar() {
  console.log(this) // [Module] { bar: [Function: bar], foo: [Function: foo] }
  return "bar" + this.foo(); // `this` points to the importing [Module] alias
  // ANTIPATTERN, and can result in undefined if imported as a named list
}

export {
  foo,
  bar
}

易碎,容易出错,因为如果使用类似// index.mjs import * as test from './foo.mjs'; console.log(test.bar()); // "barfoo" - but thanks to the wildcard and alias 的命名导入,可能会导致

TypeError:无法读取未定义的属性'foo'

并且应避免。

链接:

import { bar } from "./foo.mjs"; console.log(bar());https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import


0
投票

问题不在于您如何导出;这是this在JavaScript中的工作方式。如果在作为方法的上下文之外引用函数,则该方法的主体将没有一致的this,除非您明确绑定了该函数,并且除非有标识符绑定到该对象,否则您将无法进行任何绑定。您可以这样做,例如:

© www.soinside.com 2019 - 2024. All rights reserved.