wordpress源码-使用self::$wp_localize_scripts配合wp_localize_script()以防重复插入<script>脚本

当你使用 wp_localize_script() 时,WordPress 会在引入外部JavaScript脚本文件时,在前面插入一个<script>标签。例如:

// PHP 代码
wp_localize_script(
    'my-script', 
    'myScriptParams', 
    array(
        'text1' => 'Hello',
        'text2' => 'World'
    )
);

会生成以下 HTML:

<script>
var myScriptParams = {
    "text1": "Hello",
    "text2": "World"
};
</script>
<script src="path/to/my-script.js"></script>

若你对同一个脚本多次调用 wp_localize_script():

// 第一次本地化
wp_localize_script(
    'my-script', 
    'myScriptParams', 
    array(
        'text1' => 'Hello',
        'text2' => 'World'
    )
);

// 第二次本地化(可能在不同的钩子中)
wp_localize_script(
    'my-script', 
    'myScriptParams', 
    array(
        'text3' => 'New Value',
        'text4' => 'Another Value'
    )
);

会生成以下 HTML:

<script>
var myScriptParams = {
    "text1": "Hello",
    "text2": "World"
};
</script>
<script>
var myScriptParams = {
    "text3": "New Value",
    "text4": "Another Value"
};
</script>
<script src="path/to/my-script.js"></script>

导致全局变量myScriptParams被覆盖。因为JavaScript 的 var 允许重复声明同一变量,后声明的会覆盖前声明的值。

// 第一个脚本块
var myScriptParams = {
    "text1": "Hello",
    "text2": "World"
};

// 第二个脚本块(覆盖第一个)
var myScriptParams = {
    "text3": "New Value",
    "text4": "Another Value"
};

// 最终结果:
console.log(myScriptParams); // 输出 { text3: "New Value", text4: "Another Value" }
console.log(myScriptParams.text1); // undefined(丢失)

WooCommerce 如何避免这个问题

WooCommerce 通过 self::$wp_localize_scripts 静态数组记录已本地化的脚本,确保每个脚本只被本地化一次,如:

private static function localize_script( $handle ) {
    //  关键检查:如果脚本已本地化,直接返回
    if ( ! in_array( $handle, self::$wp_localize_scripts, true ) && wp_script_is( $handle ) ) {
        $data = self::get_script_data( $handle );

        if ( ! $data ) {
            return;
        }

        $name                        = str_replace( '-', '_', $handle ) . '_params';
        // 记录脚本已本地化
        self::$wp_localize_scripts[] = $handle;
        // 执行本地化
        wp_localize_script( $handle, $name, apply_filters( $name, $data ) );
    }
}

其中$handle就是js文件名,即my-script。这样,无论调用多少次 localize_script(‘my-script’),实际只会执行一次 wp_localize_script(),避免了全局变量覆盖。