You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

重写jQuery .val()函数生效,但getter被多次调用

问题原因分析

你遇到的两次输出“Getter”的问题,根源在于jQuery原生的<select>元素val() getter内部逻辑会调用选中<option>的val()方法——你重写的val()方法是全局生效的,所以在执行$('select').val()时会触发两次:

  1. 第一次是直接调用select的val() getter,进入你的重写方法打印“Getter”;
  2. 第二次是原生select的val()逻辑内部,遍历选中option并调用其val()方法,再次进入你的重写方法打印“Getter”。
解决方案

以下两种方案都能解决重复打印问题,同时保留你需要的核心功能:

方案一:仅针对目标元素生效

让自定义逻辑和调试打印只作用于.myselect类的select元素,其他元素直接走原生方法:

const originalVal = $.fn.val;

$.fn.extend( {
    val: function() {
        // 仅处理.myselect类select的setter逻辑
        if ( arguments.length > 0 && this.is('select.myselect') ) {
            console.log( 'Setter' );
            const result = originalVal.apply( this, arguments );
            this.trigger( 'change' );
            return result;
        }
        // 仅在.myselect类select的getter时打印调试信息
        if ( arguments.length === 0 && this.is('select.myselect') ) {
            console.log( 'Getter' );
        }
        // 所有其他情况直接调用原生val方法
        return originalVal.apply( this, arguments );
    }
} );

方案二:排除option元素的调试打印

如果你需要保留对所有元素的getter打印,只需排除option元素触发的重复输出:

const originalVal = $.fn.val;

$.fn.extend( {
    val: function() {
        if ( arguments.length > 0 ) {
            if ( this.hasClass( 'myselect' ) ) {
                console.log( 'Setter' );
                const result = originalVal.apply( this, arguments );
                this.trigger( 'change' );
                return result;
            }
            return originalVal.apply( this, arguments );
        }
        // 排除option元素的getter打印
        if ( !this.is('option') ) {
            console.log( 'Getter' );
        }
        return originalVal.apply( this, arguments );
    }
} );

内容的提问来源于stack exchange,提问作者Gavin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 06:44:50