第一天 從新認識JavaScript

一、JavaScript 嚴格模式

  • 經過在程序最開始假如一個字符串字面量 use strict ,便可開啓嚴格模式javascript

  • 嚴格模式可讓JS代碼擁有更好的兼容性,更強的健壯性java

  • 在嚴格模式下,從新聲明 arguments 會報錯,非嚴格模式則不會函數

'use strict';
function say() {
    var arguments = []; 
// Uncaught SyntaxError: Unexpected eval or arguments in strict mode
}
  • 若是鏈接兩個不一樣模式的JavaScript文件的話,若是是嚴格模式的文件放在開始的話,那麼整個文件都是處於嚴格模式code

  • 若是鏈接兩個不一樣模式的JavaScript文件的話,若是是非嚴格模式的文件放在開始的話,那麼整個文件都是處於非嚴格模式對象

  • 在文件中間使用use strict是沒有做用的ip

  • 爲了同時使用嚴格和非嚴格模式的文件,能夠經過當即調用函數達到分離做用域的目的作用域

(function() {
    // file1.js 使用了嚴格模式
    'use strict';
    function say() {

    }
})();

(function() {
    // file2.js 使用非嚴格模式
    function sayWithNoStrict() {
        var arguments = [];
    }
})();

二、注意javascript的浮點數

  • JavaScript中的數字都是 Number 類型,即雙精度浮點數,JS中整數是雙精度浮點數的一個子集字符串

  • JavaScript存在精度缺陷,如 0.1+0.2 ,應該儘可能經過單位轉換使用整數運算 1+2編譯器

  • 注意 toString()parseInt() 方法的參數string

console.log(typeof 36); // number
console.log(typeof 36.36); // number
console.log(typeof -36.36); // number

console.log(0.1 * 3.6); // 0.36000000000000004
console.log(1 * 36); // 36
console.log(1 - 0.6); // 0.4
console.log(25 / 5); // 5
console.log(2.5 / 5); // 0.5
console.log(25 % 4); // 1
console.log(25 % 0.4); // 0.19999999999999862
console.log(8 | 1); // 9

console.log((10).toString(7)); // 13 參數表示返回值的進制數
console.log(parseInt('1010', 2)); // 10 第二個參數表示須要轉換的數據的進制數,返回值爲10進制

console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + (0.2 + 0.3)); // 0.6
console.log((0.1 + 0.2) + 0.3); // 0.6000000000000001
console.log(((1 + 2) + 3) / 10); // 0.6

console.log(10 + (20 + 30)); // 60
console.log((10 + 20) + 30); // 60

三、小心隱式的強制轉換

  • String + NumberNumber會被轉爲String

  • String * NumberString會被轉爲Number

  • 要小心 NaNisNaN 的判斷與使用

console.log(3 + true); // 4

console.log(1 + 1); // 2
console.log('hello' + ' world'); // hello world

console.log(2 + '3'); // 23
console.log('2' + 3); // 23
console.log('2' + '3'); // 23

console.log(1 + '2' + 3); // 123

console.log(2 * '3'); // 6
console.log('8' | '1'); // 9

var x = NaN;
console.log(x === x); // false
var a = {};
console.log(a === a); // true
var b = null;
console.log(b === null); // true

console.log(isNaN(NaN)); // true;

console.log(isNaN({})); // true
console.log(isNaN(undefined)); //true
console.log(isNaN('foo')); // true 不能用isNaN來判斷字符串
console.log(isNaN(1)); // false
console.log(isNaN({valueOf: 'foo'})); // true

console.log(isNaN({valueOf: function(){return 1}})); // false

console.log('J' + {toString: function(){return 'S'}}); // JS
console.log(1 + {valueOf: function(){return 2}}); // 3

var obj = {
    toString: function() {
        return 'obj';
    },
    valueOf: function() {
        return 1;
    }
};

console.log(1 + obj); // 2
console.log('1' + obj); // 11


// bad
function badPoint(x, y) {
    if(!x) {
        x = 1;
    }
    if(!y) {
        y = 1;
    }
    return {
        x: x,
        y: y
    }
}

// good
function point(x, y) {
    if(typeof x === undefined || y === undefined) {
        return {
            x: x || 1,
            y: y || 1
        }
    }
    return {
        x: x,
        y: y
    }
}

console.log(badPoint(0, 0)); // { x: 1, y: 1 }
console.log(point(0, 0)); // { x: 0, y: 0 }
console.log(point()); // { x: 1, y: 1 }

四、使用原始類型替代對象包裹

  • 注意變量聲明,原始對象和封裝對象是不同的

var s = new String('hello');
console.log(s); // String {0: "h", 1: "e", 2: "l", 3: "l", 4: "o", length: 5, [[PrimitiveValue]]: "hello"}

var str = s + ' world';
console.log(str); // hello world

console.log(str[4]); // o

console.log(typeof 'hello'); // string
console.log(typeof s); // object

var s1 = new String('hello');
var s2 = new String('hello');
console.log(s1 === s2); // false
console.log(s1 == s2); // false

console.log(str.toUpperCase()); // HELLO WORLD

str.someProperty = 'some';
console.log(str.someProperty); // undefined

s.someProperty = 'some';
console.log(s.someProperty); // 'some'

五、混合類型避免使用 == 比較

  • 當使用 == 操做符進行相等的比較操做的時候,若是它的兩個參數的類型是不同的; 那麼==會把它們先強制轉換爲相同類型參數,而後再進行比較。

  • 使用 === 代表你的比較不會涉及任何的隱形的類型轉換。

  • 當對不一樣類型的數據進行比較的時候,你要首先把它們進行顯示的類型轉換。 而後再進行比較,這樣會使你的程序更加清晰。

六、分號的插入機制

  • 編譯器僅在 { 標記以前,一行的結束和程序的結束處推導分號

  • 僅在緊接着的標記不能被解析的時候推導分號

  • 在以(,[,+,-或/字符開頭的語句前決不能省略分號

  • 當腳本鏈接的時候,應在腳本之間顯式地插入分號

  • return, throw, break, continue, ++-- 的參數以前決不能換行

var b = 12;
function f() {}

// 當@1和@2連在一塊兒不可以解析的時候,分號纔會自動插入
var a = b // @1
f() // @2

// 當@3和@4連在一塊兒可以解析(雖然可能會解析失敗)的時候,分號就不會自動插入了
var c = b // @3
(f()) // @4

// 在以`[`,`(`,`+`,`-`,`/`開頭的語句前,永遠不要省略分號
var d = 8;
var e = 3  //此處的分號毫不能省略
+d
console.log(e); // 11

// 當鏈接不一樣的腳本的時候,要在不一樣的腳本之間插入分號。
(function() {
    console.log('hello')
})()
;(function() { //編寫庫函數的時候,經常在當即調用函數前添加分號,防止上一個文件最後一行無分號致使未知錯誤
    console.log('world')
})()

// 否則就會解析出錯
//(function() {
//    console.log('hello')
//})()(function() {
//    console.log('world')
//})()

// 參數以前含有`return`,`throw`,`break`,`continue`,`++`,`--`的,參數與它們之間不要換行,不然會變爲 `return;` 
function demoFunc() {
    return
    1
}
console.log(demoFunc()) // undefined 沒有返回預期的結果

// 在循環語句的頭部,分號不是用來當分隔符或者空語句使用的。
for(var i = 0; i < 3; i++) {
    console.log(i);
}

// 解析出錯
//for(var i = 0
//        i < 3
//        i++) {
//    console.log(i);
//}
相關文章
相關標籤/搜索