在JavaScript中分配对象属性会以一种奇怪的方式更改对象

Assigning an object attribute in JavaScript changes object in a weird way

本文关键字:对象 一种 方式更 分配 JavaScript 属性      更新时间:2023-09-26

我正在调试一个基于Ext的复杂JS客户端框架。我偶然发现了一行代码,它给出了我无法以任何方式解释的结果。这是一行(me实际上只是this的别名):

me.displayTplData = displayTplData;

执行之前的一些值:

me.value: "87172981"
displayTplData: Array[1]  (this is a local variable)
me.displayTplData: undefined

行后(F11,"进入下一个函数调用"):

me.value: null
displayTplData: Array[1]  (stays as before)
me.displayTplData: null

这不仅明显没有发生赋值,还改变了分配给不相关属性value的值。。。我唯一能想到的方法是displayTplData是否有一个相关的setter(类似于Python中的描述符?)。但另一方面,JS调试器在执行该行时不会介入任何代码。此外,这个框架在IE8+上运行,所以它肯定没有使用任何最新的JS开发。

FireFox和Chrome都会出现这种情况,所以肯定是"应该这样做",但我完全不明白发生了什么。

有人能猜出可能是什么原因吗对不起,我无法将其简化为一个独立的示例。

编辑:

以下是作为上下文的完整功能。

setValue: function(value, doSelect) {
    var me = this,
        valueNotFoundText = me.valueNotFoundText,
        inputEl = me.inputEl,
        i, len, record,
        dataObj,
        matchedRecords = [],
        displayTplData = [],
        processedValue = [];
    if (me.store.loading) {
        // Called while the Store is loading. Ensure it is processed by the onLoad method.
        me.value = value;
        me.setHiddenValue(me.value);
        return me;
    }
    // This method processes multi-values, so ensure value is an array.
    value = Ext.Array.from(value);
    // Loop through values, matching each from the Store, and collecting matched records
    for (i = 0, len = value.length; i < len; i++) {
        record = value[i];
        if (!record || !record.isModel) {
            record = me.findRecordByValue(record);
        }
        // record found, select it.
        if (record) {
            matchedRecords.push(record);
            displayTplData.push(record.data);
            processedValue.push(record.get(me.valueField));
        }
        // record was not found, this could happen because
        // store is not loaded or they set a value not in the store
        else {
            // If we are allowing insertion of values not represented in the Store, then push the value and
            // create a fake record data object to push as a display value for use by the displayTpl
            if (!me.forceSelection) {
                processedValue.push(value[i]);
                dataObj = {};
                dataObj[me.displayField] = value[i];
                displayTplData.push(dataObj);
                // TODO: Add config to create new records on selection of a value that has no match in the Store
            }
            // Else, if valueNotFoundText is defined, display it, otherwise display nothing for this value
            else if (Ext.isDefined(valueNotFoundText)) {
                displayTplData.push(valueNotFoundText);
            }
        }
    }
    // Set the value of this field. If we are multiselecting, then that is an array.
    me.setHiddenValue(processedValue);
    me.value = me.multiSelect ? processedValue : processedValue[0];
    if (!Ext.isDefined(me.value)) {
        me.value = null;
    }
    me.displayTplData = displayTplData; //store for getDisplayValue method   <------- this is the line
    me.lastSelection = me.valueModels = matchedRecords;
    if (inputEl && me.emptyText && !Ext.isEmpty(value)) {
        inputEl.removeCls(me.emptyCls);
    }
    // Calculate raw value from the collection of Model data
    me.setRawValue(me.getDisplayValue());
    me.checkChange();
    if (doSelect !== false) {
        me.syncSelection();
    }
    me.applyEmptyText();
    return me;
},

有时调试器会提供错误信息。奇怪的是,Firefox和Chrome的调试器都会产生相同的(错误的)检查,但如果你想确定这些值,只需在语句前后放置console.log(me.value),看看会打印出什么。

相关文章: