gpt4 book ai didi

javascript - 无法在运行时获取函数的全局执行上下文变量

转载 作者:行者123 更新时间:2023-12-03 02:15:29 26 4
gpt4 key购买 nike

我猜这是一个纯粹的 JavaScript 问题。

我需要重写一个函数showDatepicker,我这样做了:

            const Base = (Handsontable.editors.DateEditor as any).prototype as any;
const DateEditorHelper = Base.extend();

DateEditorHelper.prototype.showDatepicker = function (event: any[]) {
Base.showDatepicker.apply(this, event)

this.$datePicker.config(this.getDatePickerConfig());

var offset = this.TD.getBoundingClientRect();
var dateFormat = this.cellProperties.dateFormat || this.defaultDateFormat;
var datePickerConfig = this.$datePicker.config();
var dateStr = void 0;
var isMouseDown = this.instance.view.isMouseDown();
var isMeta = event ? (0, _unicode.isMetaKey)(event.keyCode) : false;

this.datePickerStyle.top = offset.top >= $(window).height() - 224 ? window.pageYOffset + offset.top - 224 + (0, _element.outerHeight)(this.TD) + 'px' : window.pageYOffset + offset.top + (0, _element.outerHeight)(this.TD) + 'px';
this.datePickerStyle.left = window.pageXOffset + offset.left + 'px';

this.$datePicker._onInputFocus = function () { };
datePickerConfig.format = dateFormat;

if (this.originalValue) {
dateStr = this.originalValue;

if ((0, _moment2.default)(dateStr, dateFormat, true).isValid()) {
this.$datePicker.setMoment((0, _moment2.default)(dateStr, dateFormat), true);
}

// workaround for date/time cells - pikaday resets the cell value to 12:00 AM by default, this will overwrite the value.
if (this.getValue() !== this.originalValue) {
this.setValue(this.originalValue);
}

if (!isMeta && !isMouseDown) {
this.setValue('');
}
} else if (this.cellProperties.defaultDate) {
dateStr = this.cellProperties.defaultDate;

datePickerConfig.defaultDate = dateStr;

if ((0, _moment2.default)(dateStr, dateFormat, true).isValid()) {
this.$datePicker.setMoment((0, _moment2.default)(dateStr, dateFormat), true);
}

if (!isMeta && !isMouseDown) {
this.setValue('');
}
} else {
// if a default date is not defined, set a soft-default-date: display the current day and month in the
// datepicker, but don't fill the editor input
this.$datePicker.gotoToday();
}

this.datePickerStyle.display = 'block';
this.$datePicker.show();
}

这实际上是原始函数的代码,我在其中做了一些小修改。我认为函数的内部代码变量将在运行时求值(我不是在谈论内部函数范围变量作为其参数或在其中声明的变量,而是在谈论执行上下文的全局变量)。在函数执行之前,根本没有错误(当浏览器读取函数时,它不会提示某些变量未定义),但是当它运行时,我收到此错误:

Uncaught ReferenceError: _unicode is not defined
at eval (eval at DateEditorHelper.showDatepicker (module.js?v=64fd5db96274:40281), <anonymous>:1:1)
at e.DateEditorHelper.showDatepicker (module.js?v=64fd5db96274:40281)

重写函数在与原始函数应运行的上下文相同的上下文中运行,我不知道为什么全局变量未定义。

最初的功能是一个方便的内置编辑器(datePicker)。我从 this thread 得到的最重要的想法和this

最佳答案

您说您复制了原始函数的代码并进行了细微的更改。问题似乎是您正在使用名为 _unicode 的变量。您正在定义该变量吗?

用修改后的“原始”代码替换方法的代码时,必须确保旧代码引用的任何其他变量/函数也被复制。

您必须考虑到原始方法是在另一个上下文中定义的。也许,作者并不想派生这个类,或者重写它的方法。

模块(或 IIFE)的优点是您可以定义公共(public) API,同时封装实现的私有(private)部分。当然,这意味着重写方法或函数要困难得多。

在这种情况下,变量_unicode显然是私有(private)实现的一部分。它的名称遵循以下划线开头的惯例,这一事实几乎证明了这一点。它可能是在与 DatePickerHelper 相同的模块中定义的,或者是从另一个模块导入的,但无论如何我几乎确定它没有导出,因此您无法访问它并且您的代码会失败。

为了使您的覆盖生效,您必须更改代码以避免使用该 _unicode 变量,或者按照原始代码中的相同方式自行定义它。当然,根据它的定义方式,您可能最终不得不“复制”大量代码,但这是任何尝试从外部库重写方法的 JavaScript 程序员都会遇到的问题。

让我们看一下这个“私有(private)实现”的示例:

(function() {
// this is a function I want to keep private.
function giveMeHello() {
return 'hello, ';
}

// this is the class I want to share
class Greeting {
greet(name) {
console.log(giveMeHello() + name);
}
}

window.Greeting = Greeting;
})();

const greet1 = new Greeting();
greet1.greet('Oscar'); // outputs 'hello, Oscar'.

// As a consumer of Greeting, I don't like the way if greets people. I want the name to be in uppercase
// implementation is practically identical to original code
Greeting.prototype.greet = function() {
console.log(giveMeHello() + name.toUpperCase());
};

// Let's use it!
greet1.greet('John'); // Oh! Error! giveMeHello is not defined!

正如你所看到的,在这个例子中我做了和你一样的事情。但与原始实现一样,我的实现依赖于 giveMeHello 函数。但giveMeHello 不是一个全局或公共(public)函数。从我覆盖该函数的那一刻起,我无法访问它。因此,当我执行该方法时,它失败了。

如果现在我只是在重写该方法之前复制 giveMeHello 函数,它就会起作用。

你现在明白了吗?如果您不这样做,我建议您阅读有关 JavaScript 中作用域的更多信息,这超出了 StackOverflow 的目的。

关于javascript - 无法在运行时获取函数的全局执行上下文变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49384480/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com