| name | JavaScript分析器 |
| description | 当进行JavaScript代码审查、性能优化、浏览器兼容性检查或安全审计时,分析JavaScript代码质量和最佳实践。 |
| license | MIT |
JavaScript分析器技能
概述
JavaScript的灵活性是一把双刃剑。分析代码以防止运行时意外。
核心原则: JavaScript的灵活性是一把双刃剑。分析代码以防止运行时意外。
何时使用
始终:
- JavaScript代码审查
- 性能优化
- 浏览器兼容性检查
- 安全审计
- 代码重构
- 架构设计评审
触发短语:
- "分析JavaScript代码"
- "JavaScript性能优化"
- "代码质量检查"
- "JavaScript最佳实践"
- "浏览器兼容性"
- "安全漏洞检查"
JavaScript分析功能
代码质量
- ESLint规则检查
- 代码风格统一
- 复杂度分析
- 重复代码检测
- 最佳实践验证
性能分析
- 执行时间测量
- 内存泄漏检测
- DOM操作优化
- 网络请求分析
- 渲染性能检查
安全检查
- XSS漏洞检测
- CSRF防护验证
- 输入验证检查
- 依赖安全扫描
- 敏感信息泄露
常见JavaScript问题
异步处理问题
问题:
异步操作处理不当
错误示例:
- 回调地狱
- Promise未正确处理
- async/await滥用
- 错误处理缺失
解决方案:
1. 使用async/await替代回调
2. 正确处理Promise错误
3. 避免阻塞主线程
4. 实现错误边界
内存泄漏
问题:
内存使用不当导致泄漏
错误示例:
- 事件监听器未移除
- 定时器未清理
- 闭包引用过多
- DOM节点引用未释放
解决方案:
1. 及时清理事件监听器
2. 清理定时器和间隔器
3. 避免不必要的闭包
4. 使用WeakMap/WeakSet
类型安全问题
问题:
JavaScript动态类型导致错误
错误示例:
- 类型转换错误
- 未定义属性访问
- 参数类型不匹配
- 返回值类型不确定
解决方案:
1. 使用TypeScript
2. 添加JSDoc类型注解
3. 运行时类型检查
4. 使用PropTypes
代码实现示例
JavaScript代码分析器
const fs = require('fs');
const path = require('path');
const { parse } = require('@babel/parser');
const traverse = require('@babel/traverse').default;
class JavaScriptAnalyzer {
constructor(options = {}) {
this.options = {
ecmaVersion: 2020,
sourceType: 'module',
plugins: [
'jsx',
'typescript',
'decorators-legacy',
'classProperties',
'objectRestSpread',
'asyncGenerators',
'functionBind',
'exportDefaultFrom',
'exportNamespaceFrom',
'dynamicImport',
'nullishCoalescingOperator',
'optionalChaining'
],
...options
};
this.issues = [];
this.metrics = {
totalFiles: 0,
totalLines: 0,
totalFunctions: 0,
: ,
: ,
:
};
}
() {
{
content = fs.(filePath, );
ast = .(content, filePath);
(!ast) {
{
: filePath,
: ,
: []
};
}
. = [];
.(ast, filePath);
.(ast, filePath);
.(ast, filePath);
.(ast, filePath);
.(ast, filePath);
{
: filePath,
: .,
: .(ast, content)
};
} (error) {
{
: filePath,
: error.,
: [{
: ,
: ,
: ,
: error.?. || ,
: error.?. ||
}]
};
}
}
() {
results = [];
allIssues = [];
() {
items = fs.(dir);
( item items) {
fullPath = path.(dir, item);
stat = fs.(fullPath);
(stat.()) {
(!item.() && item !== ) {
(fullPath);
}
} ((item)) {
result = .(fullPath);
results.(result);
allIssues.(...(result. || []));
}
}
}
() {
ext = path.(fileName);
[, , , , ].(ext);
}
scanDirectory.(, directory);
{
directory,
: results,
: .(allIssues),
: .(allIssues)
};
}
() {
{
(content, {
....,
: filePath
});
} (error) {
.(, error);
;
}
}
() {
.(ast, filePath);
.(ast, filePath);
.(ast, filePath);
.(ast, filePath);
}
() {
namingPatterns = {
: ,
: ,
: ,
:
};
(ast, {
(path) {
id = path..;
(id. === ) {
name = id.;
(path.. === ) {
(!namingPatterns..(name) && name !== name.()) {
..({
: ,
: ,
: ,
: id.?. || ,
: id.?. || ,
:
});
}
}
(path.. === || path.. === ) {
(!namingPatterns..(name)) {
..({
: ,
: ,
: ,
: id.?. || ,
: id.?. || ,
:
});
}
}
}
}
});
}
() {
(ast, {
(path) {
.(path, filePath);
},
(path) {
.(path, filePath);
},
(path) {
.(path, filePath);
}
});
}
() {
functionNode = path.;
startLine = functionNode.?.. || ;
endLine = functionNode.?.. || ;
lines = endLine - startLine + ;
(lines > ) {
functionName = functionNode.?. || ;
..({
: ,
: ,
: ,
: startLine,
: ,
:
});
}
}
() {
functionCalls = ();
(ast, {
(path) {
callee = path..;
(callee. === ) {
name = callee.;
line = callee.?. || ;
(!functionCalls.(name)) {
functionCalls.(name, []);
}
functionCalls.(name).(line);
}
}
});
( [name, lines] functionCalls) {
(lines. > ) {
..({
: ,
: ,
: ,
: .(...lines),
: ,
:
});
}
}
}
() {
declaredVariables = ();
usedVariables = ();
(ast, {
(path) {
id = path..;
(id. === ) {
declaredVariables.(id., {
: id.?. || ,
: id.?. ||
});
}
}
});
(ast, {
(path) {
(path.()) {
usedVariables.(path..);
}
}
});
( [name, location] declaredVariables) {
(!usedVariables.(name) && !name.()) {
..({
: ,
: ,
: ,
: location.,
: location.,
:
});
}
}
}
() {
.(ast, filePath);
.(ast, filePath);
.(ast, filePath);
}
() {
(ast, {
(path) {
callee = path..;
(callee. === ) {
object = callee.;
property = callee.;
(object. === && object. === ) {
(property. === &&
[, , ].(property.)) {
..({
: ,
: ,
: ,
: property.?. || ,
: property.?. || ,
:
});
}
}
}
}
});
}
() {
(ast, {
(path) {
callee = path..;
(callee. === &&
[, ].(callee.)) {
..({
: ,
: ,
: ,
: callee.?. || ,
: callee.?. || ,
:
});
}
}
});
}
() {
(ast, {
(path) {
callee = path..;
(callee. === ) {
property = callee.;
(property. === && property. === ) {
..({
: ,
: ,
: ,
: property.?. || ,
: property.?. || ,
:
});
}
}
}
});
}
() {
.(ast, filePath);
.(ast, filePath);
.(ast, filePath);
}
() {
(ast, {
(path) {
callee = path..;
(callee. === ) {
property = callee.;
(property. === && property. === ) {
..({
: ,
: ,
: ,
: property.?. || ,
: property.?. || ,
:
});
}
}
}
});
}
() {
(ast, {
(path) {
callee = path..;
(callee. === && callee. === ) {
..({
: ,
: ,
: ,
: callee.?. || ,
: callee.?. || ,
:
});
}
}
});
}
() {
(ast, {
(path) {
callee = path..;
(callee. === ) {
object = callee.;
property = callee.;
(object. === && object. === ) {
(property. === && property. === ) {
..({
: ,
: ,
: ,
: property.?. || ,
: property.?. || ,
:
});
}
}
}
}
});
}
() {
.(ast, filePath);
.(ast, filePath);
}
() {
(ast, {
(path) {
complexity = .(path.);
functionName = path..?. || ;
(complexity > ) {
..({
: ,
: ,
: ,
: path..?.. || ,
: ,
:
});
}
}
});
}
() {
complexity = ;
( child node. || []) {
complexity += .(child);
}
complexity;
}
() {
complexity = ;
(node.) {
:
:
:
:
:
:
:
complexity += ;
;
:
(node. === || node. === ) {
complexity += ;
}
;
}
( key node) {
(node[key] && node[key] === ) {
(.(node[key])) {
( child node[key]) {
complexity += .(child);
}
} {
complexity += .(node[key]);
}
}
}
complexity;
}
() {
(ast, {
(path) {
depth = .(path);
(depth > ) {
..({
: ,
: ,
: ,
: path..?.. || ,
: ,
:
});
}
}
});
}
() {
maxDepth = currentDepth;
( child path.().() || []) {
(child.() || child.() || child.()) {
childDepth = .(child, currentDepth + );
maxDepth = .(maxDepth, childDepth);
}
}
maxDepth;
}
() {
.(ast, filePath);
.(ast, filePath);
.(ast, filePath);
}
() {
(ast, {
(path) {
callee = path..;
(callee. === ) {
object = callee.;
property = callee.;
(object. === && object. === ) {
..({
: ,
: ,
: ,
: property.?. || ,
: property.?. || ,
:
});
}
}
}
});
}
() {
(ast, {
(path) {
callee = path..;
(callee. === &&
callee.. === &&
callee.. === ) {
parent = path.;
hasCatch = ;
(parent && parent. === ) {
parentCallee = parent..;
(parentCallee. === &&
parentCallee.. === &&
parentCallee.. === ) {
hasCatch = ;
}
}
(!hasCatch) {
..({
: ,
: ,
: ,
: callee..?. || ,
: callee..?. || ,
:
});
}
}
}
});
}
() {
hasStrictMode = ;
(ast, {
(path) {
expression = path..;
(expression. === && expression. === ) {
hasStrictMode = ;
}
}
});
(!hasStrictMode) {
..({
: ,
: ,
: ,
: ,
: ,
:
});
}
}
() {
lines = content.().;
functions = ;
classes = ;
complexity = ;
(ast, {
() { functions++; },
() { functions++; },
() { functions++; },
() { classes++; }
});
{
lines,
functions,
classes,
complexity
};
}
() {
summary = {
: issues.,
: {},
: {
: ,
: ,
:
}
};
( issue issues) {
summary.[issue.]++;
(!summary.[issue.]) {
summary.[issue.] = ;
}
summary.[issue.]++;
}
summary;
}
() {
recommendations = [];
issueCounts = {};
( issue issues) {
(!issueCounts[issue.]) {
issueCounts[issue.] = ;
}
issueCounts[issue.]++;
}
(issueCounts. > ) {
recommendations.({
: ,
: ,
:
});
}
(issueCounts. > ) {
recommendations.({
: ,
: ,
:
});
}
(issueCounts. > ) {
recommendations.({
: ,
: ,
:
});
}
(issueCounts. > ) {
recommendations.({
: ,
: ,
:
});
}
recommendations;
}
() {
str.(, letter.());
}
}
() {
analyzer = ();
fileResult = analyzer.();
.();
.();
directoryResult = analyzer.();
.();
.();
.();
( rec directoryResult.) {
.();
.();
}
}
. = ;
(. === ) {
();
}
JavaScript性能分析器
class JavaScriptPerformanceAnalyzer {
constructor() {
this.metrics = new Map();
this.observers = new Map();
}
profileFunction(name, fn) {
const wrappedFn = async (...args) => {
const startTime = performance.now();
const startMemory = this.getMemoryUsage();
try {
const result = await fn(...args);
const endTime = performance.now();
const endMemory = this.getMemoryUsage();
this.recordMetric(name, {
executionTime: endTime - startTime,
memoryDelta: endMemory - startMemory,
success: true
});
return result;
} catch (error) {
const endTime = performance.now();
const endMemory = .();
.(name, {
: endTime - startTime,
: endMemory - startMemory,
: ,
: error.
});
error;
}
};
wrappedFn;
}
() {
(!.) {
.();
;
}
observer = ( {
( entry list.()) {
(entry. === ) {
.(, {
: entry.,
: entry.,
: entry.
});
}
}
});
observer.({ : [] });
..(, observer);
{
: performance.(),
: {
performance.();
performance.(name, , );
}
};
}
() {
(!.) {
;
}
observer = ( {
( entry list.()) {
(entry. === ) {
.(, {
: entry.,
: entry.,
: entry. || ,
: .(entry.)
});
}
}
});
observer.({ : [] });
..(, observer);
observer;
}
() {
(!. || !..) {
.();
;
}
checkInterval = ( {
memory = {
: ...,
: ...,
: ...
};
.(, {
: memory.,
: memory.,
: memory.,
: memory. / memory.
});
(memory. > ) {
.(, memory.);
}
}, );
(checkInterval);
}
() {
(!..(type)) {
..(type, []);
}
..(type).({
: .(),
...data
});
records = ..(type);
(records. > ) {
records.();
}
}
() {
(. && ..) {
...;
}
;
}
() {
extension = url.().().();
typeMap = {
: ,
: ,
: ,
: ,
: ,
: ,
: ,
: ,
: ,
:
};
typeMap[extension] || ;
}
() {
report = {
: .(),
: {},
: {},
: []
};
( [type, records] .) {
report.[type] = .(type, records);
}
report. = .(report.);
report. = .(report.);
report;
}
() {
(records. === ) {
{ : };
}
analysis = {
: records.,
: records[records. - ],
: {},
: {},
: {}
};
(type) {
:
.(records, analysis);
;
:
.(records, analysis);
;
:
.(records, analysis);
;
:
.(records, analysis);
;
}
analysis;
}
() {
times = records.( r.);
memoryDeltas = records.( r.);
successRate = records.( r.). / records.;
analysis. = {
: .(times),
: .(memoryDeltas),
: successRate
};
analysis. = {
: .(...times),
: .(...memoryDeltas)
};
analysis. = {
: .(...times),
: .(...memoryDeltas)
};
}
() {
durations = records.( r.);
analysis. = {
: .(durations)
};
analysis. = {
: .(...durations)
};
analysis. = {
: .(...durations)
};
analysis. = records.(
current. > (slowest?. || ) ? current : slowest, );
}
() {
durations = records.( r.);
sizes = records.( r.);
analysis. = {
: .(durations),
: .(sizes)
};
analysis. = {
: .(...durations),
: .(...sizes)
};
analysis. = {
: .(...durations),
: .(...sizes)
};
analysis. = .(records);
}
() {
usageRatios = records.( r.);
analysis. = {
: .(usageRatios),
: .(records.( r. / / ))
};
analysis. = {
: .(...usageRatios)
};
analysis. = {
: .(...usageRatios)
};
analysis. = .(records.( r.));
}
() {
grouped = {};
( record records) {
(!grouped[record.]) {
grouped[record.] = [];
}
grouped[record.].(record);
}
( type grouped) {
typeRecords = grouped[type];
grouped[type] = {
: typeRecords.,
: .(typeRecords.( r.)),
: .(typeRecords.( r.))
};
}
grouped;
}
() {
(values. < ) ;
first = values[];
last = values[values. - ];
change = (last - first) / first;
(change > ) ;
(change < -) ;
;
}
() {
values.( sum + val, ) / values.;
}
() {
summary = {
: ,
: ,
: []
};
(metrics.) {
fnMetrics = metrics.;
(fnMetrics.. > ) {
summary..({
: ,
: ,
: fnMetrics..
});
summary. -= ;
}
}
(metrics.) {
domMetrics = metrics.;
(domMetrics.. > ) {
summary..({
: ,
: ,
: domMetrics..
});
summary. -= ;
}
}
(metrics.) {
netMetrics = metrics.;
(netMetrics.. > ) {
summary..({
: ,
: ,
: netMetrics..
});
summary. -= ;
}
}
(metrics.) {
memMetrics = metrics.;
(memMetrics.. > ) {
summary..({
: ,
: ,
: memMetrics..
});
summary. -= ;
}
}
summary. = summary..;
summary;
}
() {
recommendations = [];
(metrics. && metrics... > ) {
recommendations.({
: ,
: ,
: ,
: [
,
,
]
});
}
(metrics. && metrics... > ) {
recommendations.({
: ,
: ,
: ,
: [
,
,
]
});
}
(metrics. && metrics... > ) {
recommendations.({
: ,
: ,
: ,
: [
,
,
,
]
});
}
(metrics. && metrics... > ) {
recommendations.({
: ,
: ,
: ,
: [
,
,
,
]
});
}
recommendations;
}
() {
( observer ..()) {
observer.();
}
..();
..();
}
}
perfAnalyzer = ();
slowFunction = perfAnalyzer.(, () => {
( (resolve, ));
.();
});
domMonitor = perfAnalyzer.(.);
domMonitor.();
domMonitor.();
( {
report = perfAnalyzer.();
.(, report);
}, );
. = ;
JavaScript最佳实践
代码质量
- ESLint配置: 使用ESLint保证代码质量
- Prettier格式化: 统一代码风格
- TypeScript: 添加类型安全
- 单元测试: 保证代码可靠性
性能优化
- 懒加载: 按需加载资源
- 代码分割: 减少初始加载时间
- 缓存策略: 合理使用缓存
- 防抖节流: 优化事件处理
安全实践
- 输入验证: 验证所有用户输入
- CSP策略: 实施内容安全策略
- HTTPS: 使用安全传输
- 依赖审计: 定期检查依赖安全
相关技能
- typescript-analyzer - TypeScript分析
- react-analyzer - React分析
- nodejs-analyzer - Node.js分析
- web-performance - Web性能优化