当你使用 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(),避免了全局变量覆盖。