Chart.js 2.7.3实例化报错:scales属性缺失致'x-axis-0'赋值失败
我之前在集成Chart.js 2.7.3时也碰到过完全一致的错误,咱们来一步步分析问题根源和解决办法:
问题重现
你在现有站点中集成Chart.js 2.7.3,通过<head>引入脚本,在<body>里放置canvas并通过IIFE初始化柱状图,运行后抛出错误:
Uncaught TypeError: Cannot set property 'x-axis-0' of undefined
报错指向Chart.js第4111行的updated[id] = true;,其中updated未定义。追踪到buildOrUpdateScales方法中,updated由Object.keys(scales).reduce(...)生成,但scales取自实例的me.scales而非配置的me.options.scales,且你的实例中me.scales属性缺失。
原因分析
这个问题的核心是Chart实例初始化时,内部的scales属性未被正确创建,导致后续reduce操作异常(虽然代码里有var scales = me.scales || {},但在某些异常场景下,reduce仍可能返回undefined,比如JS环境的特殊干扰、文件完整性问题等)。常见触发场景包括:
- 引入的Chart.js文件不完整或被篡改(比如使用了非官方的自定义构建版本)
- 图表初始化时机过早,DOM或Chart类未完全加载完成
- 页面中有其他JS代码干扰了Chart的原型方法或实例属性
解决方案
尝试以下步骤逐一排查:
1. 替换为官方完整版本的Chart.js
确保你使用的是官方发布的Chart.js 2.7.3完整文件:
- 替换你当前引入的
../Chart.js文件,避免使用经过修改或裁剪的版本
2. 确保DOM完全加载后再初始化图表
虽然你的脚本放在canvas之后,但某些复杂页面环境下,仍可能出现Chart类未完全初始化的情况。可以将初始化代码包裹在DOMContentLoaded事件中:
document.addEventListener('DOMContentLoaded', function() { var ctx = document.getElementById("myChart").getContext('2d'); var myChart = new Chart(ctx, { // 你的图表配置... }); });
3. 显式配置所有坐标轴
即使使用默认配置,显式声明xAxes和yAxes可以避免Chart内部自动创建坐标轴时的异常:
options: { scales: { xAxes: [{ ticks: { beginAtZero: true } }], yAxes: [{ ticks: { beginAtZero:true } }] } }
4. 移除canvas的HTML属性width/height
让Chart.js自动处理画布尺寸,避免手动设置的尺寸与内部逻辑冲突:
<canvas id="myChart"></canvas>
(可以通过CSS设置画布的显示尺寸)
5. 检查页面其他JS代码的干扰
排查页面中是否有其他脚本修改了Object.prototype、Array.prototype或覆盖了Chart的构造函数/原型方法,这些都可能导致Chart内部逻辑异常。
内容的提问来源于stack exchange,提问作者user1754242

