The 11 JavaScript Mistakes you’re Making

Mistake 1 - You’re Using Global Variables

If you’re just getting started with JavaScript, you probably think it’s a great thing that all variables are global. Actually, if you’re just getting started, you might not know what that means. Global variables are variables that are accessible from anywhere in your JavaScript, even in different files loaded on the same page. Sounds great, doesn’t it? Any variable you might every want to change is always accessible.

Actually, no.

The reason this is a bad idea is because it’s easy to overwrite values unintentionally. Say you’ve got a web store, and you’re using JavaScript to display the price of all the items in the shopping cart (of course, you’ll recalculate this on the server side; this just enhances the user experience). Here’s some code you might have:

  1. var total = 0,    // total price  
  2.     tax   = 0.05; // 5%  

Now, let’s say that you’re also using some code you found online to display some tweets on the page … or to make a sharp little gallery for your products. They might have some code like this:

  1. var total = 15; // number of tweets pulled from twitter  

Or,

  1. var tax = function () { /* ... */ }; // Trigger Animation eXperience function  

Now, you’re in trouble: two important variables have been overwritten, and you might not even realize it; your code will be producing errors, and you’ll pay dearly in time and hair to get things working again.

So what’s the solution? In a word, encapsulation; but there are many ways to do this. Firstly, you could just write all your code within a self-invoking, anonymous function:

  1. (function () {  
  2.     var total = 0, tax = 0.05;  
  3.   
  4.     // other code  
  5. }());  

This way, absolutely no code outside the function can get to the values you have inside the function. This works for “personal” code, but it’s not so great for functionality that you want to distribute. For example, if we wanted to create a shopping cart totaller that others could use, using the module pattern would be great:

  1. var cartTotaler = (function () {  
  2.     var total = 0; tax = 0.05;  
  3.   
  4.     // other code  
  5.   
  6.     return {  
  7.       addItem : function (item) { },  
  8.       removeItem : function (item) { },  
  9.       calculateTitle : function () { }  
  10.     };  
  11. }());  

One more thing about global variable: note that if you don’t use the var keyword when creating a variable, the JavaScript engine will create a global variable by default. So:

  1. (function () {  
  2.   tax = 0.05;  
  3. }());  
  4.   
  5. var totalPrice = 100 + (100 * tax); // 105  

The variable tax is available outside the function because it’s not declared with the var keyword. Watch out for this.


Mistake 2 - You’re Not Using Semicolons

Every statement in JavaScript must end with a semicolon. It’s that simple. The issue here is that is you don’t put it in, the compiler will: this is called semicolon insertion. So the question is, if the compiler will insert them for you, why waste your time?

Well, in some places, it’s absolutely necessary; for example, you must put semicolons between the statements in a for-loop’s condition, or you’ll get a syntax error. But what about at the end of lines?

The JavaScript community is really divided on this. I’ve read very well-respected professionals on both sides of the debate. Here’s my argument: whenever you’re relying on the JavaScript compiler to change your code (even in what seems like a small way), you’re in dangerous waters.

For example, look at this simple function:

  1. function returnPerson (name) {  
  2.     return  
  3.     {  
  4.         name : name  
  5.     };  
  6. }  

This looks like it should return a cute little object … but in reality, the JavaScript compiler assumes you meant to put a semicolon after return, and will therefore return nothing; that object will get ignored. Your solution would be to do this:

  1. return {  
  2.     name : name  
  3. };  

I’m going to go with “diligently insert semicolons”; honestly, it becomes habit pretty quickly. Also, as a web developer, you’ll probably use other languages (like PHP) where semicolons are required. Why switch back and forth when you don’t have to?

Editor’s Note- Another way to look at it: unless you’re aware of every single situation where they can successfully be omitted, don’t risk it.


Mistake 3 - You’re Using ==

If you left your computer right now and walked until you met any random JavaScript developer (that might take a while), and asked him/her to give you one common JavaScript mistake, this is probably what he/she would say: “using double-equals instead of triple-equals.” What’s this mean?

Try this:

  1. if (1 == 1) {  
  2.     console.log("it's true!");  
  3. }  

You’d expect that to work, right? Well, now try this:

  1. if (1 == '1') {  
  2.     console.log("it's true!");  
  3. }  

Yes, you got “it’s true!” output to the console … and yes, that’s a bad thing. What’s going on here is that the== equality operator is coercing the values: this means it’s actually changing them to try to make the two values more similar. In this case, it’s converting the string “1” to the number 1 … so that our if-statement condition passes.

The solution here is to use ===; this doesn’t perform any type coercion, so the values are what you expect them to be. Of course, this all goes for the != and !== operators as well.

Now, for your amusement, here’s a few of the incredible inconsistencies that you’ll get if you use double-equals:

  1. ''         == '0' // false  
  2. '0'        == ''  // true  
  3. false      == '0' // true  
  4. ' \t\r\n ' == 0   // true   

Mistake 4 - You’re using Type Wrapper Objects

JavaScript kindly (um?) gives us some type wrappers for easy (um?) creation of primitive types:

  1. new Number(10);  
  2. new String("hello");  
  3. new Boolean(true);  
  4. new Object();  
  5. new Array("one""two""three");  

First off, this is just super inconvenient. All these things can be done with many fewer keystrokes:

  1. 10;  
  2. "hello";  
  3. true;  
  4. {};  
  5. ["one""two""three"];  

But, wait, there’s more: these two things aren’t exactly equal. Here’s Douglas Crockford on the topic:

For example, new boolean(false) produces an object that has a valueOfmethod that returns the wrapped value.

JavaScript: The Good Parts, page 114

This means that if you run typeof new Number(10) or typeof new String("hello"), you’ll get ‘object’—not what you want. Plus, using wrapper objects can cause behaviour that you’re not expecting if you’re used to primitive values.

So why does JavaScript provide these objects? It’s because they’re used internally. Primitive values don’t actually have methods (because they aren’t object); so, when you call a method on a primitive object (such as "hello".replace("ello", "i")), JavaScript creates a wrapper object for that string, does what you want, and then discards the object.

Leave the typed wrappers up to JavaScript and use the primitive values.

Note: this should go without saying, but I want to make this clear for the newbies: I’m not saying you shouldn’t use constructor functions and new (although some do recommend that). This advice specifically applies to primitive value types—numbers, strings, and booleans—arrays, and blank objects.


Mistake 5 - You’re not Property-Checking when Using For-In

We’re all familiar with iterating over arrays; however, you’ll probably find yourself wanting to iterate over the properties of an object. (Digression: the items in an array are actually just numbered properties in an object.) If you’ve done this before, you’ve used a for-in loop:

  1. var prop, obj = { name: "Joe", job: "Coder", age: 25 };  
  2.   
  3. for (var prop in obj) {  
  4.   console.log(prop + ": " + obj[prop]);  
  5. }  

If you run the above code, you should see this output:

  1. name: Joe  
  2. job: Coder  
  3. age: 25  

However, browsers will include properties and methods from further up the prototype chain. Most of the time you won’t want to see these when enumerating properties. You should be using the hasOwnProperties to filter out properties that aren’t actually on the object:

  1. Function Dog (name) {  
  2.     this.name = name;  
  3. }  
  4. Dog.prototype.legs = 4;  
  5. Dog.prototype.speak = function () {  
  6.     return "woof!";  
  7. };  
  8.   
  9. var d = new Dog("Bowser");  
  10.   
  11. for (var prop in d) {  
  12.     console.log( prop + ": " + d[prop] );  
  13. }  
  14.   
  15. console.log("=====");  
  16.   
  17. for (var prop in d) {  
  18.   if (d.hasOwnProperty(prop)) {  
  19.     console.log( prop + ": " + d[prop] );  
  20.   }  
  21. }  
  22.   
  23. // Output  
  24.   
  25. // name: Bowser  
  26. // legs: 4  
  27. // speak: function () {  
  28.         return "woof!";  
  29. // }  
  30. // =====  
  31. // name: Bowser  

Sometimes, you’ll want to let the properties through, but filter out any methods. You can do that by usingtypeof:

  1. for (var prop in d) {  
  2.   if (typeof d[prop] !== 'function') {  
  3.     console.log( prop + ": " + d[prop] );  
  4.   }  
  5. }  

Either way, always be sure to clarify your for-in statements to avoid unwanted results.


Mistake 6 - You’re Using with or eval

Thankfully, most sources for learning JavaScript today don’t teach you about with or eval. But if you’re using some older material—or using a less-than-reputable source (because sometimes good material is hard to find on the web)—you might have found with and eval and given them a try. Terrible move, web developer.

Let’s start with with. Two main reasons not to use it:

  1. It really slows down the execution of your JavaScript.
  2. It’s not always clear what you’re doing.

Point one stands on its own, so let’s look at the second. Quickly, here’s how with works: You pass an object to a with statement; then, inside the with statement block, you can access properties of the object as variables:

  1. var person = { name: "Joe", age : 10 };  
  2.   
  3. with (person) {  
  4.   console.log(name); // Joe  
  5.   console.log(age);  // 10  
  6. }  

But, what if we have a variable with the same name as a property of the object we’re with-ing? Basically, if both a variable and a property with the same name exist, the variable will be used. The other gotcha is that you can’t add a property to the object inside a with statement: if no property or variable exists, it will be made a variable of the scope outside the with statement:

  1. var person = { name: "Joe", age : 10 },  
  2.     name = "Billy";  
  3.   
  4. with (person) {  
  5.   console.log(name); // Billy  
  6.   job = "Designer";  
  7. }   
  8.   
  9. console.log(person.job); // undefined;  
  10. console.log(job); // Designer  

So, how about eval? In a nutshell, you can pass a string of code to the function and it will execute the code.

  1. eval( "Console.log('hello!');" );  

Sounds harmless, even powerful, right? Actually, that’s the main problem: it’s too powerful. There’s obviously no reason to just hand it a hard string that you write directly into your code, because 1) why not just write the code? And 2) eval is slower, just like with. Therefore, the primary use of eval is to execute code that you don’t have at runtime. You could be getting this from the server, or taking code directly from the user. Do you really want to give your website users complete control of your code? I hope not. Also, it opens your site up to unnumbered hackers: using eval is basically a sign that says ”I’m away, and the key is under the mat.” If you love yourself or your users: don’t use it.


Mistake 7 - You’re Not Using a Radix When Using parseInt

JavaScript has a great little helper function called parseInt that allows you to convert a string that contains a number to a number:

  1. parseInt("200"); // 200  
  2. parseInt("043"); // 35  

Um, what happened there? Shouldn’t that second example be 43? Actually, parseInt will work with more than just decimal values: so, when parseInt sees a string that starts with a 0, it assumes that it’s an octal number (base 8). That’s why it’s a mistake not to pass a radix; this tells parseInt what base the number is in (it always outputs a decimal number).

  1. parseInt("020", 10); // 20  
  2. parseInt("100", 2);  // 4  

Mistake 8 - You’re Not Using Braces on ifand while statements

One of the most obvious beauties of JavaScript is its flexibility. But sometimes, that can come back to fight you. That’s certainly the case with braces on if- and while-statement blocks. These braces are optional if you only have one line of code in the block:

  1. if (true)  
  2.   console.log("inside the if statement");  

This is great, because you can even put them on the same line:

  1. var arr = ["one""two""three""four""five""six""seven""eight""nine""ten"],  
  2.     i   = arr.length - i;  
  3.   
  4. while (i) console.log( arr[i--] );  

But this isn’t smart for a couple of reasons: firstly, it can become unclear:

  1. if (true)  
  2.   console.log("inside the if-statement.");  
  3.   console.log("outside the if-statement.");  

See what I mean? That second line isn’t in the if-statement, but it sure looks like it. Braces would make that clear. Also, if you ever want to add a line to the block, you have to remember to add the braces as well. Just adding them in the first place is so much easier. Do it.


Mistake 9 - You’re Adding Elements to the DOM Individually

All right, all right: this isn’t really JavaScript itself. But, in 99 of 100 cases, JavaScript means using the DOM. While there’s a lot of mistakes you can make when working with the DOM, this is a big one.

I fondly remember the day when I inserted my first DOM element via JavaScript. It’s fun to do, and oh-so-useful, but it unfortunately is a strain on the page: inserting a DOM element forces the browser to completely repaint the page, so if you have a whole bunch of elements to add, adding them one by one is a bad idea:

  1. var list = document.getElementById("list"),  
  2.     items = ["one""two""three""four"],  
  3.     el;  
  4.   
  5. for (var i = 0; items[i]; i++) {  
  6.   el = document.createElement("li");  
  7.   el.appendChild( document.createTextNode(items[i]) );  
  8.   list.appendChild(el); // slow, bad idea  
  9. }  

Here’s what you should do instead: use document fragments. Document fragments are a container to hold DOM elements; then instead of inserting each element individually, you can insert them all at once. The document fragment isn’t a node in itself and there will be nothing to show for it in the DOM: it’s just an invisible net for holding DOM elements before you put them into the DOM. So, here’s how you do it:

  1. var list = document.getElementById("list"),  
  2.     frag = document.createDocumentFragment(),  
  3.     items = ["one""two""three""four"],  
  4.     el;  
  5.   
  6. for (var i = 0; items[i]; i++) {  
  7.   el = document.createElement("li");  
  8.   el.appendChild( document.createTextNode(items[i]) );  
  9.   frag.appendChild(el); // better!  
  10. }  
  11.   
  12. list.appendChild(frag);  

Faster, quicker, cleaner—what’s not to love?


Mistake 10 - You’re Not Learning JavaScript

Many people don’t take the time to learn JavaScript right.

JavaScript does not equal jQuery. Did I just shock your sock off? If you found yourself guilty of committing several of the mistakes listed above, you probably need to do some serious JavaScript studying. JavaScript is a language that you can use almost without learning it, which means that so many people don’t take the time to learn it right. Don’t be one of those people: there are so many awesome JavaScript tutorials out there that you have no excuse for not learning the language. If all you know is jQuery (or Mootools, or whatever), you’re really putting yourself in a bad spot.


Mistake 11 - You’re Following all the Rules

Rules are made to be broken.

The last and final mistake you’re making is that you’re following all the rules. Yes, even some of the rules I’ve listed here. As with anything, rules are made to be broken. If you’re relatively new to JavaScript, you should probably avoid with fervour all the mistakes I’ve outlined for you today. But the truth is that if you understand why it’s recommended not to do something, that thing becomes a tool that you might use in just the right circumstance. For example, eval is preached against loudly, but it’s the only tool you can use to parse JSON from a server. Of course, there are many security checks in place when you do it (you should probably use a library). But the point is that you shouldn’t be afraid to knowledgeably use the “bad practices” I’ve listed above if the need arises. It’s the same close-mindedness that causes you to make these mistakes in the first place is the same close-mindedness that keeps you from using them when they are the right tool.

Of course, never make mistake 10 -


Conclusion

If you’re new to JavaScript, hopefully you’re a better JavaScript developer now. If you consider yourself a JavaScript pro (then how are you even still reading this?), what have I missed? Let us all know in the comments!


===========================

javascript是比較容易學的。但是,對於這門語言需要有一些值得注意的地方。本文將指出javascript編程中可能犯過的10個錯誤

錯誤1-使用全局變量

如果你剛開始javascript編程,可能會覺得全局變量很好用。事實上,剛開始javascript編程,你可能不知道使用全局變量會帶來什麼麻煩。在同一個頁面中,全局變量可以在任何內嵌的javascript代碼段中或是該頁面加載的不同的js文件中,都能訪問到。這聽起來很強大,是嗎?這就使得全局變量可以隨時隨地的被修改賦值。
事實上這樣很糟!
這樣做會導致變量在意料之外被修改重寫。假設有一個網店,需要用javascript計算並顯示購物車所有商品的價格總和(當然,服務器端還會進行重新計算,這裏只是爲了增強用戶的體驗)。可能會編寫代碼如下:

  1. var total = 0// total price
  2. tax = 0.05// 5%

現在,還需要用javascript代碼在網站上展示一些信息,或則是做一個商品倉庫。代碼如下:

  1. var total = 15// number of tweets pulled from twitter

或則是如下代碼:

  1. var tax = function () { /* ... */ }// Trigger Animation eXperience function

現在,出現問題了:兩個重要的變量被重寫,但可能還沒被意識到。這樣代碼運行會出錯,會花費很多時間來跟蹤和修復該錯誤。
那該如何解決呢?簡言之—“封裝”:當然封裝有很多方法可以實現。第一種做法是將代碼放入一個匿名的自調函數中。代碼如下:

  1. (function () {
  2.  var total = 0tax = 0.05;
  3.  
  4.  // other code
  5.  }());

這樣做,在函數外部是絕對不能訪問到函數內部定義的變量。這就形成了個人的代碼空間,但是這樣就不能公開部分方法或屬性。例如,想要創建一個購物車,定義一個總價的變量,作爲公共屬性,這種情形下可以採用模塊式編程。

  1. var cartTotaler = (function () {
  2.  var total = 0tax = 0.05;
  3.  
  4.  // other code
  5.  
  6.  return {
  7.  addItem : function (item) { },
  8.  removeItem : function (item) { },
  9.  calculateTitle : function () { }
  10.  };
  11.  }());

關於全局變量有一點值得注意,如果不用關鍵詞var來聲明創建變量,那麼javascript引擎會默認將該變量定義爲全局變量。

  1. (function () {
  2.  tax = 0.05;
  3.  }());
  4.  
  5.  var totalPrice = 100 + (100 * tax)// 105

這裏的變量tax在函數外部也是可以被訪問的,因爲在定義tax的時候沒有使用var關鍵詞。

錯誤2-不加分號

每句javascript語句必須以分號結尾。在編程時如果忘了加分號,這時javascript編解析器會自動加上。那我們在編程的時候是不是就可以完全不用浪費時間去加分號呢?
但是在一些語句中,分號是必不可少的。如for循環語句中的分號是必不可少的,否則會報語法錯誤。那麼語句末尾的分號呢?
Javascript社區已經討論過該問題。下面是本文的看法:你的代碼,只要是被javascript解析器修改過(即便是很小的修改,如添加分號),就可能會出現一些你意料之外的結果。看看下面這段javascript代碼:

  1. function returnPerson (name) {
  2.  return
  3.  {
  4.  name : name
  5.  };
  6.  }

該方法看起來會返回一個對象,但事實上,javascript解析器會在return後面緊接着添加一個分號,這就導致該函數返回undefined。Return後的對象會被忽略。解決方法很簡單,代碼如下:

  1. return {
  2.  name : name
  3.  };

在javascript編程中應嚴格要求自己添加分號,這個習慣並不難。當然,作爲一名web開發人員,你可能也會用到其他的語言(如php),這些語言都是嚴格要求以分號結尾的。你可以把這些編程語言的習慣帶到javascript編程中來。
作者註解:除了你完全肯定可以被忽略的地方,你都不可以忽略添加分號。

錯誤3-使用==

如果你問一個javascript編程者,在javascript編程中通常會犯什麼錯誤。他/她很可能會說,使用= = =來代替= =。這是什麼意思呢?
試試下面的代碼:

  1. if (1 == 1) {
  2.  console.log("it's true!");
  3.  }

代碼如你所願的輸出了“it’s true!”那再試試下面的代碼:

  1. if (1 == '1') {
  2.  console.log("it's true!");
  3.  }

這段代碼在控制檯中盡然也輸出了“it’s true!”,但其實這並不是你所期望的輸出。這裏的==運算符轉換了運算數的類型,從而使得兩個運算數相等了。這裏if語句中的==運算符使得右邊string類型的“1”變成了number型的1。
想要得到你想要的輸出,這裏應該用= = =運算符來代替= =。===不會強制轉換運算數的類型,這樣才能如你所期望的。同樣地,用!= =運算符來替換!=。下面是用==來做比較,得出的結果令人意外。

  1. '' == '0' // false
  2.  '0' == '' // true
  3.  false == '0' // true
  4.  ' \t\r\n ' == 0 // true

錯誤4-使用數據類型的包裝對象

Javascript提供了各個數據類型的包裝對象。

  1. new Number(10);
  2.  new String("hello");
  3.  new Boolean(true);
  4.  new Object();
  5.  new Array("one""two""three");

首先,它們並不好用。上面的代碼可以用更少的代碼來實現,如下:

  1. 10;
  2.  "hello";
  3.  true;
  4.  {};
  5.  ["one""two""three"];

但是這兩種方式還是有所不同的。下面是douglas crockford的觀點:
例如用new Boolean(false)創建一個對象,該對象有一個方法valueOf,調用該方法會返回構造器的值。
這意味着,如果運行typeof new Number(10)或者是typeof new String(‘hello’),將返回‘object’,而不是’number’或’string’.另外,用數據類型的包裝還會引發一些意料之外的結果。
那麼爲什麼javascript要提供數據類型的包裝對象呢?這是因爲javascript解析器內部會調用。簡單的數據類型是沒有方法的(因爲它們不是對象),所以當調用簡單類型的數據的方法時(如’hello’.replace(‘ello’, ‘i’)),javascript會調用String包裝對象來創建一個臨時的string對象,然後調用該對象的方法,完成調用後會刪除這個臨時對象。
所以不要用數據類型的包裝對象來創建簡單類型的數據。
注意:本來不用這麼說明的,但本文還是想明確的告訴初學者:不是說不使用它們和new(儘管有些是推薦使用的),這裏需要特別指出的是,這個建議特別針對這些數據類型,如:number、string、Boolean、array和空對象。

錯誤5-在使用for-in時不對屬性檢查

我們都很熟悉遍歷數組,但是你可能還希望能遍歷對象的屬性。(題外話:array事實上是屬性名爲數字的對象)。這是可以用for-in循環語句,代碼如下:

  1. var propobj = { name"Joe"job"Coder"age25 };
  2.  
  3.  for (var prop in obj) {
  4.  console.log(prop + "" + obj[prop]);
  5.  }

運行上面的代碼,輸出如下:

  1. nameJoe
  2.  jobCoder
  3.  age25

但是,瀏覽器中for-in遍歷對象屬性和方法時會包括對象原型鏈上的所有屬性和方法。但絕大多數屬性是不希望被枚舉出來的。可以用hasOwnProperties方法來檢測屬性是否屬於對象。代碼如下:

  1. Function Dog (name) {
  2.  this.name = name;
  3.  }
  4.  Dog.prototype.legs = 4;
  5.  Dog.prototype.speak = function () {
  6.  return "woof!";
  7.  };
  8.  
  9.  var d = new Dog("Bowser");
  10.  
  11.  for (var prop in d) {
  12.  console.log( prop + "" + d[prop] );
  13.  }
  14.  
  15.  console.log("=====");
  16.  
  17.  for (var prop in d) {
  18.  if (d.hasOwnProperty(prop)) {
  19.  console.log( prop + "" + d[prop] );
  20.  }
  21.  }
  22.  
  23.  // Output
  24.  
  25.  // name: Bowser
  26.  // legs: 4
  27.  // speak: function () {
  28.  return "woof!";
  29.  // }
  30.  // =====
  31.  // name: Bowser

有時,只希望枚舉列出對象的的屬性,不包括方法。可以用typeof方法,代碼如下:

  1. for (var prop in d) {
  2.  if (typeof d[prop] !== 'function') {
  3.  console.log( prop + "" + d[prop] );
  4.  }
  5.  }

不管怎麼樣,在用for-in循環時要確保對屬性進行檢測,以避免得到你意料之外的結果。

錯誤6-使用with或eval

幸運的是,現在大部分javascript教程都不會教你使用with或eval。但是一些老教程或名氣不大的資料時(因爲有時候好的資料在網上很難找到),可能會發現有使用with或eval。
下面是兩個不用with的主要原因:
1、 它會降低代碼性能
2、 不易於代碼閱讀

第一點是它與生俱來的。第二點,看看下面的代碼,這裏用with訪問person對象的name、age屬性。

  1. var person = { name"Joe"age : 10 };
  2.  
  3.  with (person) {
  4.  console.log(name)// Joe
  5.  console.log(age)// 10
  6.  }

但是,若果有一個變量和對象其中一個屬性同名,那用with會發生什麼呢?事實上,這種情況下,訪問變量會引用那個變量而不是對象的屬性。另一個值得注意的是,在with語句中,如果訪問的屬性不存在或對象不存在,就不能給對象添加屬性,同時會使得作用域鏈上with作用域後的那個作用域中創建一個變量。

  1. var person = { name"Joe"age : 10 },
  2.  name = "Billy";
  3.  
  4.  with (person) {
  5.  console.log(name)// Billy
  6.  job = "Designer";
  7.  }
  8.  
  9.  console.log(person.job)// undefined;
  10.  console.log(job)// Designer

那eval呢?它可以接受一個字符串參數,並且解析執行改字符串。

這聽起來沒有什麼不好,甚至覺得很棒,對嗎?但問題就是這太棒了!與其將一連串字符串將給它來解析執行,爲什麼不直接編寫在程序中呢?不該這麼做的原因如下:

  1. 完全可以直接編寫在代碼中。
  2. eval解析很慢的,性能跟with差不多。

eval的用法是在非運行時運行環境。可以從服務器端或客戶端獲取代碼。難道真的想你的網站用戶來底控制你的代碼?這樣不就意味着你的網站向無數的黑客敞開了大門。用eval就好比,離開了家,並告訴大家鑰匙就是門口墊子下面。如果你愛自己或你的用戶,就不要用eval。

錯誤7-在用parseInt時不用基數

Javascript提供了一個非常有用的方法parseInt,它可以將字符串轉換爲數值。

  1. parseInt("200")// 200
  2.  parseInt("043")// 35

結果是不是令人覺得意外?第二句爲什麼不是43?事實上,parseInt方法不僅僅是隻能把字符串當做十進制數來轉換。當parseInt的第一個參數是以0開頭,它就會把字符串當作是八進制數來轉換。這就是不使用基數出現的意料之外結果。第二個參數–基數,會指定parseInt方法把字符串當做什麼進制的數來轉換。(當然,它的返回值永遠是十進制數)

  1. parseInt("020"10)// 20
  2.  parseInt("100"2)// 4

錯誤8 if和while語句不使用{}

Javascript最明顯的特點是語法要求不那麼嚴格。但正是這樣的特點,有時會帶來麻煩。If和while語句的{}就會引起一些麻煩。{}是根據if條件成立時執行代碼語句的條數來用的。

  1. if (true)
  2.  console.log("inside the if statement");

這裏看起來沒什麼問題,因爲這裏的執行語句只有一句

  1. var arr = ["one""two""three""four""five""six""seven""eight""nine""ten"],
  2.  i = arr.length - i;
  3.  
  4.  while (i) console.log( arr[i--] );

但是這樣做不易於閱讀:首先,不用{}代碼結構看起來不是那麼清晰。

  1. if (true)
  2.  console.log("inside the if-statement.");
  3.  console.log("outside the if-statement.");

看看上面的代碼,第二行console語句是不屬於if執行語句的,但是這裏它看起來像是if的執行語句。使用{}會使結構更清晰。同時,如果你想在if的執行代碼中添加一句,也需要使用{}。習慣使用{}並不是一件難事。

錯誤9-單個單個地插入dom元素

這並不是javascript自身的問題。99%100的javascript編程都會涉及DOM操作,在對DOM操作上會犯很多錯誤,但這是最明顯的一個。
DOM操作會使瀏覽器重繪頁面,所以如果有一連串的元素一個接一個的插入頁面中,這會急劇增加瀏覽器渲染頁面的負擔。

  1. var list = document.getElementById("list"),
  2.  items = ["one""two""three""four"],
  3.  el;
  4.  
  5.  for (var i = 0items[i]i++) {
  6.  el = document.createElement("li");
  7.  el.appendChild( document.createTextNode(items[i]) );
  8.  list.appendChild(el)// slow, bad idea
  9.  }

Document fragments 是一個DOM元素容器,可以使用它同時添加這些元素到頁面中。Document fragment自身不是一個DOM節點,它不會在頁面DOM樹中顯示,並且在把它插入DOM之前它是不可見的。下面是它的用法:

  1. var list = document.getElementById("list"),
  2.  frag = document.createDocumentFragment(),
  3.  items = ["one""two""three""four"],
  4.  el;
  5.  
  6.  for (var i = 0items[i]i++) {
  7.  el = document.createElement("li");
  8.  el.appendChild( document.createTextNode(items[i]) );
  9.  frag.appendChild(el)// better!
  10.  }
  11.  
  12.  list.appendChild(frag);

非常快速、簡潔!

錯誤10-不懂javascript

許多人不花時間來認真地學習javascript。
Javascript並不等於jquery。這是否嚇到你了?如果你會犯以上列出的錯誤,那麼你需要認真地學習javascript。Javascript是一門語言,一門基本上不用學習就可以使用的語言,這就導致許多人不花時間來認真學習。千萬不要這麼做,已經有太多太多的教程指出這樣做的弊端,你沒有藉口不認真學習javascript。如果你只是瞭解jquery(或mootools,或別的),那麼你學習瞭解javascript的出發點就已經錯了。

錯誤11-嚴格遵循以上的規則

“Rules are made to be broken.”(規則是用來被打破的。)

雖然本文列舉了以上規則,但像任何事一樣,規則是用來被打破的。如果是剛開始學習javascript,你會嚴於律己,嚴格遵循以上規則。但是到了真正理解了爲什麼要遵循以上規則的原因後,你纔會知道靈活運用以上規則。例如,eval被反覆的說到不能用,但是它卻是唯一能解析服務器端返回json字符串的方法。當然這裏在運用它時會做很多安全的檢測(你可能會用到一個javascript庫)。這裏想要指明的是,在需要的地方,不應該害怕犯錯,大膽的運用它。當然,永遠不要犯錯誤10所指出的問題。

結論:

如果你是javascript新手,希望以上的內容對你javascript編程有所幫助。如果你是一個資深javascript工程師,如過這裏有遺漏的,請在留言板中留言告知大家。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章