이번에는 JS 던지는 오류 사용법과 JS에서 던지는 주의 사항에 대해 정리해보겠습니다. 실제 사례를 살펴보겠습니다.
JS에서 오류를 던지는 것은 예술입니다. 코드에서 오류를 발생시키는 것이 적절한 위치를 파악하는 데는 시간이 걸립니다. 따라서 이 사실을 파악하고 나면 코드를 디버깅하는 시간이 훨씬 단축되고 코드에 대한 만족도가 극적으로 높아질 것입니다.
오류의 본질
프로그램은 예상치 못한 일이 발생하면 오류를 발생시킵니다. 잘못된 값이 함수에 전달되었거나 수학 연산에서 잘못된 피연산자가 발견되었을 수 있습니다. 프로그래밍 언어는 기본 규칙 세트를 정의합니다. 이러한 규칙을 벗어나면 오류가 발생하며 개발자는 코드를 수정할 수 있습니다. 오류가 발생하지 않거나 보고되지 않으면 디버깅이 매우 어렵습니다. 모든 실패가 침묵한다면 첫 번째 문제는 그것을 격리하고 고치는 것은 물론이고 그것을 찾는데 많은 시간이 걸릴 것이라는 점이다. 따라서 오류는 개발자의 적이 아니라 친구입니다.
예상치 못한 장소와 부적절한 시기에 오류가 자주 발생하는데, 이는 매우 번거로운 일입니다. 더 나쁜 것은 기본 오류 메시지가 너무 간결하여 정확히 무엇이 잘못되었는지 설명하지 못하는 경우가 많습니다. JS 오류 메시지는 드물고 비밀스러운 것으로 악명 높으며(특히 이전 버전의 IE에서) 문제를 더욱 악화시킬 뿐입니다. "이러한 조건이 발생했기 때문에 이 함수 호출이 실패했습니다."라는 오류가 뜬다고 상상해 보세요. 그러면 디버깅 작업이 즉시 쉬워지며, 이는 오류를 직접 발생시키는 이점입니다.
오류를 내장된 실패 사례처럼 생각하는 것은 매우 도움이 됩니다. 모든 곳에서 실패를 예상하는 것보다 코드의 특정 위치에서 실패를 계획하는 것이 훨씬 쉽습니다. 이는 코딩뿐만 아니라 제품 디자인에서도 매우 일반적인 관행입니다. 자동차에는 충격이 발생할 때 프레임이 예측 가능한 방식으로 붕괴되도록 설계된 충돌 흡수 영역도 있습니다. 충돌이 발생했을 때 이러한 프레임이 어떻게 반응하는지, 특히 어떤 부품이 고장날지 알면 제조업체는 승객을 안전하게 지킬 수 있습니다. 코드도 이런 방식으로 생성할 수 있습니다.
JS에서 오류 발생
웹 측 디버깅의 복잡성으로 인해 JS에서 오류를 발생시키는 것이 다른 언어에서 동일한 작업을 수행하는 것보다 더 가치 있다는 것은 의심의 여지가 없습니다. throw 연산자를 사용하여 제공된 객체를 오류로 던질 수 있습니다. 모든 유형의 개체가 오류로 발생할 수 있지만 오류 개체가 가장 일반적으로 사용됩니다.
throw new Error('Something bad happened.');
내장된 오류 유형은 모든 JS 구현에서 유효합니다. 해당 생성자는 오류 메시지를 참조하는 하나의 매개변수만 허용합니다. 이러한 방식으로 오류가 발생하면 브라우저는 일반적으로 try-catch 문에 의해 포착되지 않으면 메시지(메시지 문자열)를 직접 표시합니다. 오늘날 대부분의 브라우저에는 오류가 발생하면 오류 메시지가 출력되는 콘솔이 있습니다. 즉, 던진 오류와 던지지 않은 오류는 모두 동일한 방식으로 처리됩니다.
경험이 부족한 개발자는 때때로 다음과 같은 문자열을 오류로 직접 던집니다.
// 不好的写法throw 'message';
실제로 오류가 발생할 수 있지만 모든 브라우저가 예상대로 응답하지는 않습니다. Firefox, Opera 및 Chrome은 모두 "잡히지 않은 예외" 메시지를 표시하며 위의 메시지 문자열을 포함합니다. Safari와 IE는 위의 메시지 문자열을 전혀 제공하지 않고 단순히 "잡히지 않은 예외" 오류를 발생시키며 이는 디버깅에 도움이 되지 않습니다.
원한다면 어떤 종류의 데이터든 버릴 수 있습니다. 제약조건이 특정 데이터 유형일 수 없다는 규칙은 없습니다.
throw { name: 'Nicholas' };throw true;throw 12345;throw new Date();
한 가지 명심해야 할 점은, 던져진 값이 try-catch 문에 의해 포착되지 않으면 오류가 발생한다는 것입니다. Firefox, Opera 및 Chrome은 모두 오류 메시지의 표시 논리를 완성하기 위해 발생한 값에 대해 String() 함수를 호출하지만 Safari 및 IE에서는 그렇지 않습니다. 모든 브라우저에서 오류 없이 사용자 정의 오류 메시지를 표시하는 유일한 방법은 Error 객체를 사용하는 것입니다.
오류 발생의 이점
직접 오류를 발생시키면 브라우저에 표시할 정확한 텍스트를 사용할 수 있습니다. 행 및 열 번호 외에도 문제를 디버깅하는 데 필요한 모든 정보를 포함할 수 있습니다. 항상 오류 메시지에 함수 이름과 함수가 실패한 이유를 포함하는 것이 좋습니다. 다음 함수를 살펴보세요.
function getDivs (element) { return element.getElementsByTagName('div'); }
이 함수는 요소 요소 아래의 모든 하위 요소 중에서 div 요소를 가져오도록 설계되었습니다. 작동할 함수에 전달되는 DOM 요소에 null 값을 전달하는 것이 일반적일 수 있지만 실제로 필요한 것은 DOM 요소입니다. 이 함수에 null을 전달하면 어떻게 되나요? "개체 예상"과 유사한 모호한 오류 메시지가 표시됩니다. 그런 다음 실행 스택을 살펴보고 실제로 소스 파일에서 문제를 찾아야 합니다. 오류를 발생시키면 디버깅이 더 쉬워집니다:
function getDivs (element) { if (element && element.getElementsByTagName) { return element.getElementsByTagName('div'); } else { throw new Error('getDivs(): Argument must be a DOM element.'); } }
现在给getDivs()函数抛出一个错误,任何时候只要element不满足继续执行的条件,就会抛出一个错误明确地陈述发生的问题。如果在浏览器控制台中输出该错误,你马上能开始调试,并知道最有可能导致该错误的原因是调用函数试图用一个值为null的DOM元素去做进一步的事情。
我倾向于认为抛出错误就像给自己留下告诉自己为什么失败的标签。
何时抛出错误
理解了如何抛出错误只是等式的一个部分,另外一部分就是要理解什么时候抛出错误。由于JS没有类型和参数检查,大量的开发者错误地假设他们自己应该实现每个函数的类型检查。这种做法并不实际,并且会对脚本的整体性能造成影响。考察下面的函数,它试图实现充分的类型检查。
// 不好的做法:检查了太多的错误function addClass (element, className) { if (!element || typeof element.className !== 'string') { throw new Error('addClass(): First argument must be a DOM element.'); } if (typeof className !== 'string') { throw new Error('addClass(): Second argument must be a string.'); } element.className += '' + className; }
这个函数本来只是简单地给一个给定的元素增加一个CSS类名(className),因此,函数的大部分工作变成了错误检查。纵然它能在每个函数中检查每个参数(模仿静态语言),在JS中这么做也会引起过度的杀伤。辨识代码中哪些部分在特定的情况下最有可能导致失败,并只在那些地方抛出错误才是关键所在。
在上例中,最有可能引发错误的是给函数传递一个null引用值。如果第二个参数是null或者一个数字或者一个布尔值是不会抛出错误的,因为JS会将其强制转换为字符串。那意味着导致DOM元素的显示不符合期望,但这并不至于提高到严重错误的程度。所以,我只会检查DOM元素。
// 好的写法function addClass (element, className) { if (!element || typeof element.className !== 'string') { throw new Error('addClass(): First argument must be a DOM element.'); } element.className += '' + className; }
如果一个函数只被已知的实体调用,错误检查很可能没有必要(这个案例是私有函数);如果不能提前确定函数会被调用的所有地方,你很可能需要一些错误检查。这就更有可能从抛出自己的错误中获益。抛出错误最佳的地方是在工具函数中,如addClass()函数,它是通用脚本环境中的一部分,会在很多地方使用,更准确的案例是JS类库。
针对已知条件引发的错误,所有的JS类库都应该从它们的公共接口里抛出错误。如jQuery、YUI和Dojo等大型的库,不可能预料你在何时何地调用了它们的函数。当你做错事的时候通知你是它们的责任,因为你不可能进入库代码中去调试错误的原因。函数调用栈应该在进入库代码接口时就终止,不应该更深了。没有比看到由一打库代码中函数调用时发生一个错误更加糟糕的事情了吧,库的开发者应该承担起防止类似情况发生的责任。
私有JS库也类似。许多Web应用程序都有自己专用的内置的JS库或“拿来”一些有名的开源类库(类似jQuery)。类库提供了对脏的实现细节的抽象,目的是让开发者用得更爽。抛出错误有助于对开发者安全地隐藏这些脏的实现细节。
这里有一些关于抛出错误很好的经验法则:
一旦修复了一个很难调试的错误,尝试增加一两个自定义错误。当再次发生错误时,这将有助于更容易地解决问题。
如果正在编写代码,思考一下:“我希望[某些事情]不会发生,如果发生,我的代码会一团糟糕”。这时,如果“某些事情”发生,就抛出一个错误。
如果正在编写的代码别人(不知道是谁)也会使用,思考一下他们使用的方式,在特定的情况下抛出错误。
请牢记,我们目的不是防止错误,而是在错误发生时能更加容易地调试。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
위 내용은 JS에서 발생한 오류 사용 요약의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!