10 个 JavaScript 容易犯的错误
JavaScript 是一门简单的解释性编程语言,学习他很容易,但是语言语法去不严谨,这就导致了很容易犯错,但是却不知道错误在哪里,今天给大家列举一下 10 个 JavaScript 容易犯的错误,也许你也这么干过?
1、失踪的大括号
JavaScript 经常犯的错误是省略括号后面的声明,比如:if
、else
、 while
和 for
。虽然这是允许的,你必须格外小心,因为这种做法往往是隐藏的问题和错误的来源。看下面的例子:
// Say hello to Gandalfhello('Gandalf');
function hello(name){
// This code doesn't do what the indentation implies!
if(name === undefined)
console.log('Please enter a username!');
fail();
// The following line is never reached:
success(name);
}
function success(name){
console.log('Hello, ' + name + '!');
}
function fail(){
throw new Error("Name is missing. Can't say hello!");
}
虽然 fail()
函数是缩进的,看起来好像是属于 if 语句。所以大括号总是围绕其中的代码块是一个很好的做法,即使是只有一个语句。
2、缺少分号
当 JavaScript 解析,有一个过程称为自动分号的插入。顾名思义,解析器是乐意把你丢失分号。此功能的目的是使 JavaScript 更平易近人,更容易写的初学者。然而你应该总是包含分号,因为有在忽略他们的危险。这里有一个例子:
console.log('Welcome the fellowship!')['Frodo', 'Gandalf', 'Legolas', 'Gimli'].forEach(function(name){
hello(name)
})
function hello(name){
console.log('Hello, ' + name + '!')
}
因为有一个分号在 3 行失踪,解析器假设开始第五行是一个尝试使用数组语法访问属性访问器,而不是一个独立的数组,这不是我们所期望的,在一个类型错误的结果。解决方法是简单的–总是写分号。 一些有经验的 JavaScript 开发者喜欢把分号但是,他们非常清楚的错误,这可能会导致和知道如何阻止他们。
3、变量类型强制转换
JavaScript 是动态类型。这意味着,你不需要指定类型时,宣布一个新的变量,并可以自由转让或将其价值。这使得写的不是像 C 或 Java 非常容易,但是你打开门,潜在的错误,在其他语言被编译步骤期间。这里有一个例子:
var textBox = document.querySelector('input');textBox.addEventListener('input', function(){
// textBox.value holds a string. Adding 10 appends
// the string '10', it doesn't perform an addition..
console.log(textBox.value + ' + 10 = ' + (textBox.value + 10));
});
这个问题可以通过使用固定的容易 parseInt(textBox.value, 10)
将字符串转换为数字前加 10。 取决于你如何使用变量,运行时可能会决定它应该在一种或另一种类型转换。这是众所周知的类型强制。为了防止类型的隐式转换比较时,变量如果报表,您可以使用严格的平等的检查(===)。
4、忘了 var
另一种做法,初学者是有罪的,被遗忘的使用 var
关键词时,变量的声明。JavaScript 是非常宽容的,并在第一时间看到你使用一个可变的无 var
语句,它将为你默默地宣布全球。这可以是微妙的错误源。这里有一个例子,这也显示出不同的错误–缺少逗号时声明多个变量一次:
var a = 1, b = 2, c = 3;function alphabet(str){
var a = 'A', b = 'B' // Oops, missing ',' here!
c = 'C', d = 'D';
return str + ' ' + a + b + c + '…';
}
console.log( alphabet("Let's say the alphabet!") );
// Oh no! Something went wrong! c has a new value!
console.log(a, b, c);
当解析器达到 4 线,它会自动插入一个分号,然后解释 C 和 D 5 号线的声明为全局。这将导致外部 C 变量的值的变化。
5、浮动小数的运算
几乎所有的编程语言都有这个错误,包括 JavaScript 。由于道路浮点数在内存中表示算术运算,并没有你想的那么精确。这里有一个例子:
var a = 0.1, b = 0.2;// Surprise! this is false:
console.log(a + b == 0.3);
// Because 0.1 + 0.2 does not produce the number that you expect:
console.log('0.1 + 0.2 = ', a + b);阅读更多JavaScript的陷阱在这里。
为了解决这个问题,你不应该使用小数,如果你需要绝对正确使用整数。
6、在文字使用构造函数
当 Java 和 C 程序员开始编写 JavaScript,他们通常更喜欢使用构造函数创建对象:new Array()
、 new Object()
、new String()
。虽然他们都非常支持,建议使用文字符号:[]{}""
,因为构造函数有微妙的特点:
/* Using array constructors is valid, but not recommended. Here is why. */// Create an array with four elements:
var elem4 = new Array(1,2,3,4);
console.log('Four element array: ' + elem4.length);
// Create an array with one element. It doesn't do what you think it does:
var elem1 = new Array(23);
console.log('One element array? ' + elem1.length);
/* String objects also have their warts */
var str1 = new String('JavaScript'),
str2 = "JavaScript";
// Strict equality breaks:
console.log("Is str1 the same as str2?", str1 === str2);
解决的方法很简单:尝试总是使用文字符号。
7、不知道变量的作用范围
初学者的一个难以理解的概念是 JavaScript 的作用域规则和关闭。这是理所当然的:
// Print the numbers from 1 to 10, 100ms apart. Or not.for(var i = 0; i < 10; i++){
setTimeout(function(){
console.log(i+1);
}, 100*i);
}
/* To fix the bug, wrap the code in a self-executing function expression:
for(var i = 0; i < 10; i++){
(function(i){
setTimeout(function(){
console.log(i+1);
}, 100*i);
})(i);
}
*/
功能保留的能见度变量在其父母的范围。但是,因为我们有一个延缓执行 setTimeout
的时候,功能,实际运行,循环已经完成 I
变量递增到 11。 自我评论工作执行的功能,因为它复制 I
变量的值和保持一个私人复制每个超时功能。
8、使用 eval
它被认为是一种不好的做法,当你使用它的时候,有一个更好、更快的方法。
/* Using eval to access properties dynamically */var obj = {
name: 'Foo Barski',
age: 30,
profession: 'Programmer'
};
// Which property to access?
var access = 'profession';
// This is a bad practice. Please don't do it:
console.log( eval('obj.name + " is a " + obj.' + access) );
// Instead, use array notation to access properties dynamically:
console.log( obj.name + " is a " + obj[access]);
/* Using eval in setTimout */
// Also bad practice. It is slow and difficult to read and debug:
setTimeout(' if(obj.age == 30) console.log("This is eval-ed code, " + obj[access] + "!");', 100);
// This is better:
setTimeout(function(){
if(obj.age == 30){
console.log('This code is not eval-ed, ' + obj[access] + '!');
}
}, 100);
eval
是一个字符串。调试从 eval 块所产生的信息是难以理解的,你要逃避的单和双引号。更不用说它比 JavaScript 慢。不要使用 eval,除非你知道你正在做什么。
9、不了解异步代码
有一些独特的 JavaScript,几乎一切都是异步的,你需要通过回调函数来通知事件。这不直观的初学者,他们很快就发现自己抓头上的错误,是很难理解的。这里有一个例子中,我使用 freegeoip 获取你的位置的 IP 服务:
var userData = {};// Fetch the location data for the current user.
load();
// Output the location of the user. Oops, it doesn't work! Why?
console.log('Hello! Your IP address is ' + userData.ip + ' and your country is ' + userData.country_name);
// The load function will detect the current visitor's ip and location with ajax, using the
// freegeoip service. It will place the returned data in the userData variable when it's ready.
function load(){
$.getJSON('http://freegeoip.net/json/?callback=?', function(response){
userData = response;
// Uncomment this line to see what is returned:
// console.log(response);
});
}
即使 console.log
之后 load()
函数调用,它实际上是在执行读取数据。
10、滥用事件侦听器
让我们说,你想要听一个按钮点击,但只有一个复选框。这里是如何一个初学者可能做它(jQuery):
var checkbox = $('input[type=checkbox]'),button = $('button');
// We want to listen for clicks only when the checkbox is marked.
checkbox.on('change', function(){
// Is the checkbox checked?
if(this.checked){
// Listen for clicks on the button.
button.on('click', function(){
// This alert is called more than once. Why?
alert('Hello!');
});
}
});
这显然是错误的。理想情况下,你应该倾听事件只有一次,就像我们是复选框的变化事件。在按钮上绑定多个 button.on('click')
事件侦听器,是永远不会被删除,结果我将把它作为为读者做这工作的一个练习。
以上是 10 个 JavaScript 容易犯的错误 的全部内容, 来源链接: utcz.com/p/231911.html