使用JavaScript类的Setters和Getters时触发Uncaught TypeError
解决JavaScript类中setter/getter调用startsWith()报错问题
问题描述
尝试在JavaScript类中通过setter和getter将url字段处理为包含value、domain、icon属性的对象时,调用url.startsWith()出现错误:Uncaught TypeError: url.startsWith is not a function。已知需用下划线前缀属性避免setter/getter与属性名冲突,示例代码如下:
HTML代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body style="background-color: #333;"> <script src="./main.js" type="module"></script> </body> </html>
原JS代码
class Url{ constructor(url){ this.url = { value : url, domain : url.startsWith('https://') ? url.split(8) : url.split(7), icon : url + 'favicon.ico' } } get url(){ return this._url } set url(url){ this._url = { value : url, domain : url.startsWith('https://') ? url.split(8) : url.split(7), icon : url + 'favicon.ico' } } } const test = new Url("https://youtube.com") console.log(test.url.domain)
错误原因
- 构造函数触发setter时参数类型错误:构造函数中直接给
this.url赋值一个对象,这会触发setter方法,此时setter接收的参数是这个对象而非原始字符串url。对象没有startsWith()方法,因此报错。 - split方法使用错误:
split()需要传入分隔符字符串,而非数字,原代码中url.split(8)无法正确截取域名。
修复后的代码
class Url{ constructor(url){ // 传入原始字符串触发setter,确保参数为字符串类型 this.url = url; } get url(){ return this._url; } set url(urlStr){ let domain; // 判断协议类型,用slice截取域名部分 if(urlStr.startsWith('https://')){ domain = urlStr.slice(8); } else if(urlStr.startsWith('http://')){ domain = urlStr.slice(7); } else { domain = urlStr; } this._url = { value: urlStr, domain: domain, // 修正icon路径拼接方式 icon: `${urlStr}/favicon.ico` }; } } const test = new Url("https://youtube.com"); console.log(test.url.domain); // 输出: youtube.com
修复说明
- 构造函数中通过
this.url = url传入原始字符串,保证setter接收的参数是字符串,可正常调用startsWith()。 - 将
split()替换为slice(),正确截取协议后的域名部分。 - 增加
http://协议的判断及默认情况处理,提升代码鲁棒性。 - 修正
icon路径的拼接逻辑,避免出现无效路径。
内容的提问来源于stack exchange,提问作者strjak
相关产品推荐
相关产品推荐

