Do write portable code

本文探讨了JavaScript中数组末尾多余逗号导致的浏览器兼容性问题及解决方法,并介绍了在不同浏览器环境下时间字符串解析差异的应对策略。

最近遇到两个 bug ,都是因为代码写得不具有可移植性而造成的。Javascript 本身就由于浏览器的差异有许多需要注意的地方,写代码的时候一定要万分小心,多多测试。

数组常量值末尾多余的逗号

Javascript 里面用类似 [1,2,3] 的方法来初始化数组是众所周知的。但是有一个地方却比较容易犯错误。特别是对于熟悉 C 语言的人来说,C 语言里面明确说明,以下这种情况里面,多余的逗号是可以接受的:

int array[] = {1,2,};

然而作为一个弱类型的语言,语法相对会比较随意的 javascript ,在这里却有一个陷井。事实上,标准可以允许中间或着头部的位置出现多余的逗号,这样会把多余的 undefined 的对象加入到数组中。不过末尾的逗号却会因为浏览器的不同而产生不同的结果。例如

var arr = [1,2,3,];
alert(arr.length);

在 IE6 下会得到 4 ,而在 Firefox 2 下得到的是 3 。且不论谁对谁错,但这已经是不得不去面对的事实了。这次我就遇到了这个问题,事实上,我是在 rails 的 ERB 模板里面生成一个 javascript 的数组常量。大概像这个样子:

var data = [
    <% for entry in @entries -%>
        <%= format_entry entry %>,
    <% end -%>
    ];

这样产生了末尾多余的逗号,导致了在 Firefox 和 IE 下产生了不同的结果。最后对最后一个元素特殊对待才解决了问题:

var data = [
    <% for entry in @entries[0..-2] -%>
        <%= format_entry entry %>,
    <% end -%>
    <%= format_entry @entries[-1] %>
    ];

时间的格式

我要在 javascript 里面通过字符串解析出时间来。在 Ruby 里面的 Time 类有一个方便的 to_s 方法可以直接把时间转化为字符串,它得到的格式是这样的 Tue Sep 04 13:48:25 +0800 2007 。我便直接使用了这个格式,一直都是好好的,后来拿到 IE 下面去跑的时候,根本跑不出结果来。调试了很久才发现 IE 下面没有能把那个时间解析出来,IE 不认那个 “+0800″ 。最后我用 strftime 格式化成了一种通用的格式把这个问题解决了。

标题基于Python的汽车之家网站舆情分析系统研究AI更换标题第1章引言阐述汽车之家网站舆情分析的研究背景、意义、国内外研究现状、论文方法及创新点。1.1研究背景与意义说明汽车之家网站舆情分析对汽车行业及消费者的重要性。1.2国内外研究现状概述国内外在汽车舆情分析领域的研究进展与成果。1.3论文方法及创新点介绍本文采用的研究方法及相较于前人的创新之处。第2章相关理论总结和评述舆情分析、Python编程及网络爬虫相关理论。2.1舆情分析理论阐述舆情分析的基本概念、流程及关键技术。2.2Python编程基础介绍Python语言特点及其在数据分析中的应用。2.3网络爬虫技术说明网络爬虫的原理及在舆情数据收集中的应用。第3章系统设计详细描述基于Python的汽车之家网站舆情分析系统的设计方案。3.1系统架构设计给出系统的整体架构,包括数据收集、处理、分析及展示模块。3.2数据收集模块设计介绍如何利用网络爬虫技术收集汽车之家网站的舆情数据。3.3数据处理与分析模块设计阐述数据处理流程及舆情分析算法的选择与实现。第4章系统实现与测试介绍系统的实现过程及测试方法,确保系统稳定可靠。4.1系统实现环境列出系统实现所需的软件、硬件环境及开发工具。4.2系统实现过程详细描述系统各模块的实现步骤及代码实现细节。4.3系统测试方法介绍系统测试的方法、测试用例及测试结果分析。第5章研究结果与分析呈现系统运行结果,分析舆情数据,提出见解。5.1舆情数据可视化展示通过图表等形式展示舆情数据的分布、趋势等特征。5.2舆情分析结果解读对舆情分析结果进行解读,提出对汽车行业的见解。5.3对比方法分析将本系统与其他舆情分析系统进行对比,分析优劣。第6章结论与展望总结研究成果,提出未来研究方向。6.1研究结论概括本文的主要研究成果及对汽车之家网站舆情分析的贡献。6.2展望指出系统存在的不足及未来改进方向,展望舆情
【磁场】扩展卡尔曼滤波器用于利用高斯过程回归进行磁场SLAM研究(Matlab代码实现)内容概要:本文介绍了利用扩展卡尔曼滤波器(EKF)结合高斯过程回归(GPR)进行磁场辅助的SLAM(同步定位与地图构建)研究,并提供了完整的Matlab代码实现。该方法通过高斯过程回归对磁场空间进行建模,有效捕捉磁场分布的非线性特征,同时利用扩展卡尔曼滤波器融合传感器数据,实现移动机器人在复杂环境中的精确定位与地图构建。研究重点在于提升室内等无GPS环境下定位系统的精度与鲁棒性,尤其适用于磁场特征明显的场景。文中详细阐述了算法原理、数学模型构建、状态估计流程及仿真实验设计。; 适合人群:具备一定Matlab编程基础,熟悉机器人感知、导航或状态估计相关理论的研究生、科研人员及从事SLAM算法开发的工程师。; 使用场景及目标:①应用于室内机器人、AGV等在缺乏GPS信号环境下的高精度定位与地图构建;②为磁场SLAM系统的设计与优化提供算法参考和技术验证平台;③帮助研究人员深入理解EKF与GPR在非线性系统中的融合机制及实际应用方法。; 阅读建议:建议读者结合Matlab代码逐模块分析算法实现细节,重点关注高斯过程回归的训练与预测过程以及EKF的状态更新逻辑,可通过替换实际磁场数据进行实验验证,进一步拓展至多源传感器融合场景。
WARNING: Enabling and disabling experimental features do not take effect until next start of PowerShell. WARNING: Enabling and disabling experimental features do not take effect until next start of PowerShell. [PS7 19:25:05] C:\Users\Administrator\Desktop [master] > # 增强版 Install-Socat 函数(修复下载源问题) [PS7 19:25:13] C:\Users\Administrator\Desktop [master] > function Install-Socat { >> param( >> [Parameter(Mandatory = $false)] >> [string]$InstallDrive = "E:", >> >> [Parameter(Mandatory = $false)] >> [string]$InstallDir = "Program Files\Socat" >> ) >> >> # 1. 规范化路径处理 >> $fullPath = [System.IO.Path]::GetFullPath("$InstallDrive\$InstallDir").TrimEnd('\') >> >> # 2. 验证文件系统权限 >> if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { >> Write-Warning "需要管理员权限安装程序" >> return $null >> } >> >> # 3. 检查现有安装 >> $existingPath = (Get-Command socat -ErrorAction SilentlyContinue | >> Select-Object -ExpandProperty Source -First 1) ?? $null >> >> if ($existingPath) { >> Write-Host "已安装于: $existingPath" -ForegroundColor Green >> return $existingPath >> } >> >> # 4. 创建安装目录 >> try { >> if (-not (Test-Path $fullPath)) { >> $null = New-Item -Path $fullPath -ItemType Directory -Force >> } >> } catch { >> Write-Error "创建目录失败: $($_.Exception.Message)" >> return $null >> } >> >> # 5. 文件下载(更新有效的下载源) >> $tempFile = Join-Path $env:TEMP "socat-win64.zip" >> $downloadUrls = @( >> # 官方镜像源 >> "https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip", >> "https://downloads.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip?ts=$(Get-Date -UFormat %s)", >> >> # 备用镜像源 >> "https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip", >> "https://cfhcable.dl.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip", >> "https://altushost-swe.dl.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip" >> ) >> >> $validDownload = $false >> $lastError = $null >> >> foreach ($downloadUrl in $downloadUrls) { >> try { >> # 清除旧下载 >> if (Test-Path $tempFile) { >> Remove-Item $tempFile -Force -ErrorAction SilentlyContinue >> } >> >> # 下载文件 >> Write-Host "尝试从 $downloadUrl 下载..." -ForegroundColor Cyan >> $ProgressPreference = 'SilentlyContinue' >> >> try { >> Invoke-WebRequest $downloadUrl -OutFile $tempFile -UseBasicParsing -RetryIntervalSec 3 -ErrorAction Stop >> } catch { >> $lastError = $_.Exception.Message >> Write-Warning "下载失败 ($downloadUrl): $lastError" >> continue >> } >> >> # 验证文件大小(最小1MB) >> $fileInfo = Get-Item $tempFile -ErrorAction Stop >> if ($fileInfo.Length -lt 1MB) { >> $lastError = "文件过小 ($([math]::Round($fileInfo.Length/1KB)) KB)" >> Write-Warning "文件校验失败: $lastError" >> continue >> } >> >> # 验证ZIP文件完整性 >> try { >> Add-Type -AssemblyName System.IO.Compression.FileSystem -ErrorAction Stop >> $archive = [System.IO.Compression.ZipFile]::OpenRead($tempFile) >> $entryCount = $archive.Entries.Count >> $archive.Dispose() >> >> if ($entryCount -eq 0) { >> $lastError = "空压缩包" >> Write-Warning "文件校验失败: $lastError" >> continue >> } >> >> $validDownload = $true >> Write-Host "成功下载并验证: $downloadUrl" -ForegroundColor Green >> break >> } catch { >> $lastError = $_.Exception.Message >> Write-Warning "文件校验失败: $lastError" >> } >> } catch { >> $lastError = $_.Exception.Message >> Write-Warning "下载过程中出错: $lastError" >> } finally { >> $ProgressPreference = 'Continue' >> } >> } >> >> if (-not $validDownload) { >> Write-Error "所有下载源均失败。最后错误: $lastError" >> Write-Host @" >> 无法自动下载socat。请手动执行以下操作: >> 1. 从以下链接下载socat: >> https://github.com/portapps/socat-portable/releases >> 2. 解压到: $fullPath >> 3. 将以下路径添加到系统PATH环境变量: >> $fullPath >> "@ -ForegroundColor Yellow >> return $null >> } >> >> # 6. 解压缩 >> try { >> # 确保目标目录存在 >> if (-not (Test-Path $fullPath)) { >> $null = New-Item -Path $fullPath -ItemType Directory -Force >> } >> >> # 使用.NET方法解压 >> Add-Type -AssemblyName System.IO.Compression.FileSystem >> [System.IO.Compression.ZipFile]::ExtractToDirectory($tempFile, $fullPath) >> >> $socatExe = Join-Path $fullPath "socat.exe" >> >> if (-not (Test-Path $socatExe -PathType Leaf)) { >> throw "解压后未找到 socat.exe" >> } >> } catch { >> Write-Error "解压失败: $($_.Exception.Message)" >> return $null >> } >> >> # 7. 环境变量更新 >> $currentPath = [Environment]::GetEnvironmentVariable("Path", "Machine") >> if ($currentPath -notlike "*$fullPath*") { >> $newPath = $currentPath + ";$fullPath" >> [Environment]::SetEnvironmentVariable("Path", $newPath, "Machine") >> } >> >> # 8. 更新当前会话PATH >> $env:Path += ";$fullPath" >> >> # 9. 返回完整路径 >> if (Test-Path $socatExe) { >> Write-Host "socat 安装成功: $socatExe" -ForegroundColor Green >> return $socatExe.ToString() >> } else { >> Write-Error "安装后文件验证失败" >> return $null >> } >> } [PS7 19:25:14] C:\Users\Administrator\Desktop [master] > [PS7 19:25:14] C:\Users\Administrator\Desktop [master] > # 增强版 New-TcpTunnel 函数(保持不变) [PS7 19:25:14] C:\Users\Administrator\Desktop [master] > function New-TcpTunnel { >> param( >> [int]$LocalPort = 8443, >> [string]$RemoteHost = "google.com", >> [int]$RemotePort = 443, >> [string]$SocatPath = $null >> ) >> >> # 1. 获取socat路径 >> $socatBinary = if ($SocatPath -and (Test-Path $SocatPath)) { >> $SocatPath.ToString() >> } else { >> $installedPath = Install-Socat >> if (-not $installedPath) { >> throw "socat安装失败" >> } >> $installedPath.ToString() >> } >> >> # 2. 创建日志文件 >> $logTime = Get-Date -Format "yyyyMMdd-HHmmss" >> $stdOutFile = Join-Path $env:TEMP "socat-$LocalPort-$logTime-out.log" >> $stdErrFile = Join-Path $env:TEMP "socat-$LocalPort-$logTime-err.log" >> >> # 3. 启动进程 >> try { >> $processArgs = @{ >> FilePath = $socatBinary >> ArgumentList = "TCP-LISTEN:$LocalPort,fork,reuseaddr TCP:$($RemoteHost):$RemotePort" >> NoNewWindow = $true >> RedirectStandardOutput = $stdOutFile >> RedirectStandardError = $stdErrFile >> PassThru = $true >> } >> >> $process = Start-Process @processArgs >> } catch { >> Write-Error "启动socat失败: $($_.Exception.Message)" >> if (Test-Path $stdErrFile) { >> Write-Warning "错误日志内容: $(Get-Content $stdErrFile -Raw)" >> } >> throw >> } >> >> # 4. 验证端口监听 >> $portActive = $false >> 1..5 | ForEach-Object { >> Start-Sleep -Seconds 1 >> if (-not $portActive) { >> $portStatus = Get-NetTCPConnection -LocalPort $LocalPort -ErrorAction SilentlyContinue >> $portActive = [bool]$portStatus >> } >> } >> >> if (-not $portActive) { >> Write-Warning "端口 $LocalPort 状态: 未监听" >> if (Test-Path $stdErrFile) { >> Write-Warning "错误日志: $(Get-Content $stdErrFile -Raw)" >> } >> throw "隧道创建失败,端口 $LocalPort 未监听" >> } >> >> # 5. 返回进程信息 >> return [PSCustomObject]@{ >> Process = $process >> Port = $LocalPort >> StdOutLog = $stdOutFile >> StdErrLog = $stdErrFile >> } >> } [PS7 19:25:14] C:\Users\Administrator\Desktop [master] > # 测试安装函数 [PS7 19:25:20] C:\Users\Administrator\Desktop [master] > $socatPath = Install-Socat -Verbose 尝试从 https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip 下载... VERBOSE: Requested HTTP/1.1 GET with 0-byte payload VERBOSE: Received HTTP/1.1 9-byte response of content type text/plain WARNING: 下载失败 (https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip): Response status code does not indicate success: 404 (Not Found). 尝试从 https://downloads.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip?ts=1757157921 下载... VERBOSE: Requested HTTP/1.1 GET with 0-byte payload VERBOSE: Received HTTP/1.1 response of content type text/html of unknown size VERBOSE: File Name: socat-win64.zip WARNING: 文件校验失败: 文件过小 (102 KB) 尝试从 https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip 下载... VERBOSE: Requested HTTP/1.1 GET with 0-byte payload VERBOSE: Received HTTP/1.1 9-byte response of content type text/plain WARNING: 下载失败 (https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip): Response status code does not indicate success: 404 (Not Found). 尝试从 https://cfhcable.dl.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip 下载... VERBOSE: Requested HTTP/1.1 GET with 0-byte payload WARNING: 下载失败 (https://cfhcable.dl.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip): 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 (cfhcable.dl.sourceforge.net:443) 尝试从 https://altushost-swe.dl.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip 下载... VERBOSE: Requested HTTP/1.1 GET with 0-byte payload VERBOSE: Received HTTP/1.1 response of content type text/html of unknown size VERBOSE: File Name: socat-win64.zip WARNING: 文件校验失败: 文件过小 (102 KB) Install-Socat: 所有下载源均失败。最后错误: 文件过小 (102 KB) 无法自动下载socat。请手动执行以下操作: 1. 从以下链接下载socat: https://github.com/portapps/socat-portable/releases 2. 解压到: E:\Program Files\Socat 3. 将以下路径添加到系统PATH环境变量: E:\Program Files\Socat [PS7 19:25:58] C:\Users\Administrator\Desktop [master] > [PS7 19:25:58] C:\Users\Administrator\Desktop [master] > # 验证安装 [PS7 19:25:58] C:\Users\Administrator\Desktop [master] > if ($socatPath) { >> socat -V >> Write-Host "socat 安装成功" -ForegroundColor Green >> } [PS7 19:25:58] C:\Users\Administrator\Desktop [master] > # 创建到HTTP服务的隧道 [PS7 19:26:10] C:\Users\Administrator\Desktop [master] > $tunnel = New-TcpTunnel -LocalPort 8080 -RemoteHost "example.com" -RemotePort 80 尝试从 https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip 下载... WARNING: 下载失败 (https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip): Response status code does not indicate success: 404 (Not Found). 尝试从 https://downloads.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip?ts=1757157971 下载... WARNING: 文件校验失败: 文件过小 (102 KB) 尝试从 https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip 下载... WARNING: 下载失败 (https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip): Response status code does not indicate success: 404 (Not Found). 尝试从 https://cfhcable.dl.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip 下载... WARNING: 下载失败 (https://cfhcable.dl.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip): 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 (cfhcable.dl.sourceforge.net:443) 尝试从 https://altushost-swe.dl.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip 下载... WARNING: 文件校验失败: 文件过小 (102 KB) Install-Socat: Line | 13 | $installedPath = Install-Socat | ~~~~~~~~~~~~~ | 所有下载源均失败。最后错误: 文件过小 (102 KB) 无法自动下载socat。请手动执行以下操作: 1. 从以下链接下载socat: https://github.com/portapps/socat-portable/releases 2. 解压到: E:\Program Files\Socat 3. 将以下路径添加到系统PATH环境变量: E:\Program Files\Socat Exception: Line | 15 | throw "socat安装失败" | ~~~~~~~~~~~~~~~~~ | socat安装失败 [PS7 19:26:48] C:\Users\Administrator\Desktop [master] > [PS7 19:26:48] C:\Users\Administrator\Desktop [master] > # 测试隧道 [PS7 19:26:48] C:\Users\Administrator\Desktop [master] > Start-Process "http://localhost:$($tunnel.Port)" [PS7 19:26:48] C:\Users\Administrator\Desktop [master] > [PS7 19:26:48] C:\Users\Administrator\Desktop [master] > # 监控日志 [PS7 19:26:48] C:\Users\Administrator\Desktop [master] > Get-Content $tunnel.StdErrLog -Wait -Tail 10 Get-Content: Cannot bind argument to parameter 'Path' because it is null. [PS7 19:26:48] C:\Users\Administrator\Desktop [master] > $cacheFile = "C:\ProgramData\socat-cache\socat-win64.zip" [PS7 19:27:07] C:\Users\Administrator\Desktop [master] > if (Test-Path $cacheFile) { >> Copy-Item $cacheFile $tempFile >> $validDownload = $true >> } [PS7 19:27:07] C:\Users\Administrator\Desktop [master] >
09-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值