Types
null undefined boolean number string object symbol(es6)
除了object,都叫基本類型
用typeof來檢測types:
typeof NaN === 'number //true
typeof Infinity === 'number' //true
typeof undefned ==='undefined'
typeof null === 'object' //true
typeof Symbol() === 'symbol' // true
typeof function a(){ /* .. */ } === "function"; // true
typeof [1,2,3] === "object"; // true
//未出現的變量
typeof a; // "undefined"
//檢驗null:
var a = null;
(!a && typeof a === 'object');// true
null === null //true
檢查全局變量 :
if (window.DEBUG) {
// ..
}
//安全檢測
(typeof x !== 'undefined') ?
變量提升
if(false){var y}, 這種情況y也被聲明瞭,undefined
Values
Array:
delete,刪除後,剩下一個undefined,並不會改變長度
x = [1,2] delete x[0] , x // [undefined,2]
數組的類對象表現與長度:
var a = [ ];
a[0] = 1;
//不算在長度裏面
a["foobar"] = 2;
a.length; // 1
而如果是字符數字,則看作數字
var a = [ ];
a["13"] = 42;
a.length; // 14
2.類數組(含有0:xx,1:xx..類似)轉化爲數組
###1
function foo() {
var arr = Array.prototype.slice.call( arguments );
arr.push( "bam" );
console.log( arr );
}
foo( "bar", "baz" ); // ["bar","baz","bam"]
###2
var arr = Array.from( arguments );
Strings
1.字符串和數組有些相似,concat,indexOf,.length等
但字符串是immutable,
x = 'aa'
x[0] = 'o';
x// 'aa' 沒變
字符串不可變的一個結果就是,任意對字符串的改變都會return a new string,
2.字符串可以借用數組的方法,join(),map
a = "foo"
var c = Array.prototype.join.call( a, "-" );
var d = Array.prototype.map.call( a, function(v){
return v.toUpperCase() + ".";
} ).join( "" );
c//f-0-0
d//F.0.0
由於字符串的immutable特性,不能借用reverse()
//這樣做:var c = a.split("").reverse().join("");
//複雜unicode 不適用
Number
雙浮點數保存
1.確定小數點後的數:toFiexed(x>=0)
var a = 42.59;
a.toFixed( 0 ); // "43"
a.toFixed( 1 ); // "42.6"
確定實際位數:toPrecision(x>=1)
var a = 42.59;
a.toPrecision( 1 ); // "4e+1"
a.toPrecision( 2 ); // "43"
a.toPrecision( 3 ); // "42.6"
你可以直接用數字後接這些方法,不用用變量保存值再引用這些方法
0.21.toPrecision(1) // 0.2,
2.特例注意
// invalid syntax:
42.toFixed( 3 ); // SyntaxError
// these are all valid:
(42).toFixed( 3 ); // "42.000"
0.42.toFixed( 3 ); // "0.420"
42..toFixed( 3 ); // "42.000"
3.進制轉換(儘量用小寫,)
0xf3; // hexadecimal for: 243
0Xf3; // ditto
0363; // octal for: 243
//eS6
0o363; // octal for: 243
0O363; // ditto
0b11110011; // binary for: 243
0B11110011; // ditto
var x=110;
alert(x);
alert(x.toString(8));
alert(x.toString(32));
alert(x.toString(16));
//其他轉十進制
var x='110';
alert(parseInt(x,2));
alert(parseInt(x,8));
alert(parseInt(x,16));
//其他轉其他
//先用parseInt轉成十進制再用toString轉到目標進制
alert(String.fromCharCode(parseInt(141,8)))
alert(parseInt('ff',16).toString(2));
4.小數值的不確定問題,用Number.EPSILON
0.1 + 0.2 === 0.3; // false
function numbersCloseEnoughToEqual(n1,n2) {
return Math.abs( n1 - n2 ) < Number.EPSILON;
}
var a = 0.1 + 0.2;
var b = 0.3;
numbersCloseEnoughToEqual( a, b ); // true
numbersCloseEnoughToEqual( 0.0000001, 0.0000002 ); // false
5.判斷是否是整數
2 === 2.00 //true,被看作整數
Number.isInteger()
Number.isInteger( 42 ); // true
Number.isInteger( 42.000 ); // true
Number.isInteger( 42.3 ); // false
Number.isSafeInteger( Number.MAX_SAFE_INTEGER ); // true
Number.isSafeInteger( Math.pow( 2, 53 ) ); // false
Number.isSafeInteger( Math.pow( 2, 53 ) - 1 ); // true
6.Undefined
undefined 可以作爲標識符使用,也可以被修改,但不要這樣使用
function foo() {
undefined = 2; // really bad idea!
}
foo();
function foo() {
"use strict";
undefined = 2; // TypeError!
}
foo();
function foo() {
"use strict";
var undefined = 2;
console.log( undefined ); // 2
}
foo();
void x(x任意都行)返回undefined
7.NaN
typeof NaN === 'number'
NaN === NaN // false
判斷NaN:
(1): isNaN,判斷一切非數字包括NaN
var a = 2 / "foo";
var b = "foo"
isNaN( a ); // true
isNaN( b ); // true
(2):Es6: Number.isNaN() 只判斷NaN
var a = 2 / "foo";
var b = "foo";
Number.isNaN( a ); // true
Number.isNaN( b ); // false -- phew!
···
(3)將它和它自己比較
NaN === NaN //fasle
8.Infinity
var a = 1 / 0; // Infinity
var b = -1 / 0; // -Infinity
Infinity/Infinity // NaN
-3/Infinity // -0
+3/Infinity // 0
9.0 & -0
作用僅僅是爲了判斷變化趨勢是什麼,負數到0還是正數到0
判斷函數
function isNegZero(n) {
n = Number( n );
return (n === 0) && (1 / n === -Infinity);
}
isNegZero( -0 ); // true
isNegZero( 0 / -3 ); // true
isNegZero( 0 ); // false
+"-0"; // -0
Number( "-0" ); // -0
JSON.parse( "-0" ); // -0
var a = -0
a.toString(); // "0"
a + ""; // "0"
String( a ); // "0"
// strangely, even JSON gets in on the deception
JSON.stringify( a ); // "0"
10.超級相等
Object.is(a,b)
var a = 2 / "foo";
var b = -3 * 0;
Object.is( a, NaN ); // true
Object.is( b, -0 ); // true
Object.is( b, 0 ); // false
11.Value vs. Reference
基本類型:null, undefined, string, number, boolean, and ES6’s symbol
傳入value的複製值
對象(數組)傳入pointer(引用指針)
注意下面的例子,foo(a)並沒有真正的傳入a,只是把a的引用指針複製給了x,也就是說a,x都是指向同樣的數組
但當x重新賦值後,就不再指向a的那個數組了
function foo(x) {
x.push( 4 );
x; // [1,2,3,4]
// later
x = [4,5,6];
x.push( 7 );
x; // [4,5,6,7]
}
var a = [1,2,3];
foo( a );
a; // [1,2,3,4] not [4,5,6,7]
如果不想影響a的指向,指向傳入那個數組,可以用foo(a.slice())
想要改值,必須把值包裝成對象裏的屬性
function foo(wrapper) {
wrapper.a = 42;
}
var obj = {
a: 2
};
foo( obj );
obj.a; // 42
Natives
1.native constructors:
String()
Number()
Boolean()
Array()
Object()
Function()
RegExp()
Date()
Error()
Symbol()
注意下面的表現:
new+natives 出來的是打包的Object,有內部clsss,並且console.log(a)的結果分瀏覽器不同
var a = new String( "abc" );
typeof a; // "object" ... not "String"
a instanceof String; // true
Object.prototype.toString.call( a ); // "[object String]"
Object.prototype.toString.call( [1,2,3] ); // "[object Array]"
//特例:
Object.prototype.toString.call( null ); // "[object Null]"
Object.prototype.toString.call( undefined ); // "[object Undefined]"ji
//基本類型值 自動打包,用new Number()等 反而更慢
Object.prototype.toString.call( "abc" ); // "[object String]"
Object.prototype.toString.call( 42 ); // "[object Number]"
Object.prototype.toString.call( true ); // "[object Boolean]"
注意判斷:
var a = new Boolean( false );
if (!a) {
console.log( "Oops" ); // never runs
}
if('false'){console.log(12)} //12 會打印
1.native constructors:
String()
Number()
Boolean()
Array()
Object()
Function()
RegExp()
Date()
Error()
Symbol()
注意下面的表現:
new+natives 出來的是打包的Object,有內部clsss,並且console.log(a)的結果分瀏覽器不同
var a = new String( "abc" );
typeof a; // "object" ... not "String"
a instanceof String; // true
Object.prototype.toString.call( a ); // "[object String]"
Object.prototype.toString.call( [1,2,3] ); // "[object Array]"
//特例:
Object.prototype.toString.call( null ); // "[object Null]"
Object.prototype.toString.call( undefined ); // "[object Undefined]"ji
//基本類型值 自動打包boxing,用new Number()等 反而更慢
Object.prototype.toString.call( "abc" ); // "[object String]"
Object.prototype.toString.call( 42 ); // "[object Number]"
Object.prototype.toString.call( true ); // "[object Boolean]"
注意判斷:
var a = new Boolean( false );
if (a) {
console.log( "Oops" ); // runs
}
if (Boolean(false)) {
console.log( "Oops" ); // never runs
}
if('false'){console.log(12)} //12 runs
//注意下面
unboxing: .valueOf()
a.toString()// 'false' if中判斷就是true
a.valueOf()// false if中判斷就是fasle
2.探究 [undefined] 和 [ undefined x 1 ]內空的關係
var a = new Array( 3 );
var b = [ undefined, undefined, undefined ];
var c = [];
c.length = 3;
//對chrome來說結果是下面這樣:(不同的瀏覽器顯示結果不同)
a// [ undefined x 3 ]
b// [ undefined, undefined, undefined ]
c// [ undefined x 3 ]
a與c是一樣的
a.join( "-" ); // "--"
b.join( "-" ); // "--"
a.map(function(v,i){ return i; }); // [ undefined x 3 ]
b.map(function(v,i){ return i; }); // [ 0, 1, 2 ]
因爲a中undefined就是不存在的,只是顯示的”undefined”,因此map迭代不了,一定得避免使用空白slot
如果想要手動創造[undefined…]:
var a = Array.apply( null, { length: 3 } ); //第二個對象是類數組對象,每一個值都是undefiend,傳了三個undefined參數進去
a; // [ undefined, undefined, undefined ]
- Date() & Error()
Date(),結果是字符串的時間
new Date()是對象,
new Date()
//Mon Aug 07 2017 13:26:42 GMT+0800 (馬來西亞半島標準時間)
new Date().getTime(); Date.now()
//1502083738834 1970.1.1 毫秒級
4.Symbol
作用:values that can be used as properties on objects with little fear of any collision
前面不能加new
5.native prototype
String#substr(..), String#substring(..), and String#slice(..):
Function.prototype is a function, RegExp.prototype is a regular expression,
### Coverting Values
1.coertion的結果總是scalar primitive values:
string,number,boolean
**1.ToString**
1.Abstract Value Operations
toString(): 如果對象有自定義的toString,則調用自定義的,
當Coercion
var a = 1.07 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000;
// seven times three digits => 21 digits
a.toString(); // “1.07e21”
null.toString();// error
undefined.toString();// error
null + ”; ‘null’
undefined + ”; ‘undefiend’
var a = [1,2,3];
a.toString(); // “1,2,3”
var b = {a:1};
b.toString(); // “[object Object]”
2..JSON Stringification :JSON.stringify()
功能和toString()有點像
JSON.stringify( “42” ); // “”42”” (a string with a quoted string value in it)
JSON.stringify( null ); // “null”
JSON.stringify( true ); // “true”
//會自動略過undefined,function and symbol :undefined
//無限引用的對象會報錯
JSON.stringify( undefined ); // undefined
JSON.stringify( function(){} ); // undefined
JSON.stringify( [1,undefined,function(){},4] ); // “[1,null,null,4]”
JSON.stringify( { a:2, b:function(){} } ); // “{“a”:2}”
如果一個對象有toJSON()方法,則先引用它
a.toJSON = functioin(){}…
toString(x,replacer)第二個參數可以是一個數組或函數,過濾結果的作用
var a = {
b: 42,
c: “42”,
d: [1,2,3]
};
JSON.stringify( a, [“b”,”c”] ); // “{“b”:42,”c”:”42”}”
JSON.stringify( a, function(k,v){
if (k !== “c”) return v;
} );
// “{“b”:42,”d”:[1,2,3]}”
toString(x,replacer,space)第三個參數,控制縮排,僅供參考
var a = {
b: 42,
c: “42”,
d: [1,2,3]
};
JSON.stringify( a, null, 3 );
// “{
// “b”: 42,
// “c”: “42”,
// “d”: [
// 1,
// 2,
// 3
// ]
// }”
JSON.stringify( a, null, “—–” );
// “{
// —–“b”: 42,
// —–“c”: “42”,
// —–“d”: [
// ———-1,
// ———-2,
// ———-3
// —–]
// }”
**2.ToNumber**
Number(undefined) //NaN
Number(true) //1
Number(false) //0
Number(null) //0
Number([]) //0
Number(”) //0
Number({}) //
//與上面對比:
1+{} //”1[object Object]”
1+[] //’1’
//對象和數組轉換時,會先找valueOf(),再找toString()
var a = {
valueOf: function(){sn
return “42”;
}
};
var b = {
toString: function(){
return “42”;
}
};
var c = [4,2];
c.toString = function(){
return this.join( “” ); // “42”
};
Number( a ); // 42
Number( b ); // 42
Number( c ); // 42
Number( [ “abc” ] ); // NaN
[] + {}
**3.ToBoolean**
(1).falsy values 下面轉換時爲false
null
undefined
fasle
+0 -0 NaN
“”
(2).Falsy Objects:
var a = new Boolean( false );
var b = new Number( 0 );
var c = new String( “” );
var d = Boolean( a && b && c );
d; // true
唯一的對象轉換boolean爲false,判斷是否是老版本IE
Boolean(document.all)//false
(3).Truthy Values
var a = “false”;
var b = “0”;
var c = “””;
var d = Boolean( a && b && c );
var a = []; // empty array – truthy or falsy?
var b = {}; // empty object – truthy or falsy?
var c = function(){}; // empty function – truthy or falsy?
var d = Boolean( a && b && c );
**4.Explicit Coercion**
(1).Strings <-> Numbers
Number()
String()
toString()
+
// equal to x = Date.now()//
//x = new Date().getTime()
x = +new Date()
(2). ~ & |
| 按位取或
~ 按位去反: 相當於-(x+1)
~42; // -(42+1) ==> -43
//可以用來作爲if()條件判斷:判斷x是否是-1
var a = “Hello World”;
~a.indexOf( “lo” ); // -4 <– truthy!
if (~a.indexOf( “lo” )) { // true
// found it!
}
~a.indexOf( “ol” ); // 0 <– falsy!
!~a.indexOf( “ol” ); // true
if (!~a.indexOf( “ol” )) { // true
// not found!
}
~~ x和 x|0的特別作用:保留整數部分;對比Math
~~2.5 // 2
~~(-2.5) //-2
2.5 | 0 // 2
(-2.5) | 0 //-2
對比Math.floor,Math.round,Math.ceil的負數部分
//返回小於x的最大整數
Math.floor(-0.4) // -1
Math.floor(-0.5) // -1
//Math.round(x) = Math.floor(x+0.5)
Math.round(-0.4) //-0
Math.round(-0.5) //-0
Math.round(-0.6) //-1
//返回大於x的最小整數
Math.ceil(-0.4) //-0
Math.ceil(-0.5) //-0
(3).Parsing Numeric Strings解析包含數字的字符串
parseInt(x,y),x必須是字符串,如果不是字符串 ,則調用隱式轉換ToString.
y爲表示x是幾進制,在pre-es5環境下,會考慮八進制,小心
parseInt(‘1231sdasd123’) //1231
parseFloat(‘1.23xzxzdsa’) //1.23
parseInt()第一個參數的隱式轉換!
parseInt(‘Infinity’,19) //18
parseInt( 0.000008 ); // 0 (“0” from “0.000008”)
parseInt( 0.0000008 ); // 8 (“8” from “8e-7”)
parseInt( false, 16 ); // 250 (“fa” from “false”)
parseInt( parseInt, 16 ); // 15 (“f” from “function..”)
parseInt( “0x10” ); // 16
parseInt( “103”, 2 ); // 2
4.Explicitly * --> Boolean
(1)用Boolean(x)去顯式轉換~ see above
(2) 用!! 效果和Boolean(x)一樣
**5.Implicit Coercion**
1.Implicitly: Strings <--> Numbers
(1). ➕
加號兩邊有string,則轉化爲string結合
否則爲數字加,(ToNumber) 先valueOd(),後toString()
var a = 42;
var b = a + “”;
b; // “42”
//先valueOd()失敗,後toString()
var a = [1,2];
var b = [3,4];
a + b; // “1,23,4”
對象➕
var a = {
valueOf: function() { return 42; },
toString: function() { return 4; }
};
a + “”; // “42” //先調用valueOf(),若沒有,再調用toString()
String( a ); // “4”直接調用toString()
(2).string -->number ➖0/*/1\1
var a = “3.14”;
var b = a - 0;
b; // 3.14
var a = [3];
var b = [1];
a - b; // 2
2.Implicitly: Booleans --> Numbers
用作多重判斷時,如只有一個爲真
function onlyOne() {
var sum = 0;
for (var i=0; i < arguments.length; i++) {
sum += Number( !!arguments[i] );
}
return sum === 1;
}
3.Implicitly: * --> Boolean
&& ||的真正作用
爲操作數選擇器運算符
結果總是比較的數之一
a || b;
// roughly equivalent to:
a ? a : b;
a && b;
// roughly equivalent to:
a ? b : a;
var a = 42;
var b = “abc”;
var c = null;
a || b; // 42
a && b; // “abc”
c || b; // “abc”
c && b; // null
4.Symbol Coercion
Boolean(Symbol) //true
5. == vs ===
(1) == 允許implicity coercion,===不允許
NaN is never equal to itself (see Chapter 2)
+0 and -0 are equal to each other (see Chapter 2)
(2)Comparing: strings to numbers
轉換爲數字再比較
(3)Comparing: anything to boolean
Boolean轉換爲數字再比較
var a = “42”;
var b = true;
a == b; // false
(4)Comparing: nulls to undefineds
null 這兩兄弟 相互轉化和相等
null == undefined //true
null === undefined //false
(5) objects to non-objects
對象轉化爲基本類型再判斷
var a = 42;
var b = [ 42 ];
a == b; // true
var a = “abc”;
var b = Object( a ); // same as new String( a )
a === b; // false
a == b; // true
三兄弟都是false
var a = null;
var b = Object( a ); // same as Object()
a == b; // false
var c = undefined;
var d = Object( c ); // same as Object()
c == d; // false
var e = NaN;
var f = Object( e ); // same as new Number( e )
e == f; // false
(6)Edge Cases
“0” == false; // true – UH OH!
false == 0; // true – UH OH!
false == “”; // true – UH OH!
false == []; // true – UH OH!
“” == 0; // true – UH OH!
“” == []; // true – UH OH!
0 == []; // true – UH OH!
[] == ![]; // true
2 == [2]; // true
“” == [null]; // true
0 == “\n”; // true
0 == ” “; // true
“true” == true; // false
(7) Abstract Relational Comparison > <
兩步: -1. 首先ToPrimitive,如果有結果不是string,那麼就調用ToNumber,接着再比較 -2.如果結果都是string,則直接一個一個字符比較
var a = [ 42 ];
var b = [ "43" ];
a < b; // true
b < a; // false
var a = [ "42" ];
var b = [ "043" ];
a < b; // false
var a = [ 4, 2 ];
var b = [ 0, 4, 3 ];
a < b; // false
//特別之處, >= 的邏輯是 !<
var a = { b: 42 };
var b = { b: 43 };
a < b; // false
a == b; // false
a > b; // false
a <= b; // true
a >= b; // true
Grammer
Statements & Expressions
Statement Completion Values
(下面的這個好像沒什麼用…)
–implicit return of the last statement value in the block.
statements是完整的語句,expressions最終會有一個確定的值
var a = 3 * 6;
var b = a;
b;
上面,3行都是statement,a = 3 * 6,b = a,3*6,a,b等是expressions;
var a, b;
a = if (true) {
b = 4 + 38;
};
console中會出現一個42結果..
Expression Side Effects
1.
var a = 42;
var b = (a++);
a; // 43
b; // 42
對比下面
var a = 42;
var b = (a++,a);//運算子優先順序
a; // 43
b; // 42
2.delete
var obj = {
a: 42
};
obj.a; // 42
delete obj.a; // true
obj.a; // undefined
//delete obj.a會return true:
if(delete obj.a){console.log("return true")};//
3.= = =chained assignments
var a, b, c;
a = b = c = 42;//a b c都是42
Contextual Rules,根據場景和使用者確定不同的rules
1.{} curly braces
(1).Object Literals
var a = {
foo:bar()
}
(2).Labels //標籤的作用
- label in for loop:
此處是continue foo標籤所標記的那個loop的下一輪loop
{
foo:bar()
}
foo: for (var i=0; i<4; i++) {
for (var j=0; j<4; j++) {
// whenever the loops meet, continue outer loop
if (j == i) {
// jump to the next iteration of
// the `foo` labeled-loop
continue foo;
}
// skip odd multiples
if ((j * i) % 2 == 1) {
// normal (non-labeled) `continue` of inner loop
continue;
}
console.log( i, j );
}
}
// 1 0
// 2 0
// 2 1
// 3 0
// 3 2
對比上面,加入break,功能是直接break出label標記的那個loop
// `foo` labeled-loop
foo: for (var i=0; i<4; i++) {
for (var j=0; j<4; j++) {
if ((i * j) >= 3) {
console.log( "stopping!", i, j );
// break out of the `foo` labeled loop
break foo;
}
console.log( i, j );
}
}
// 0 0
// 0 1
// 0 2
// 0 3
// 1 0
// 1 1
// 1 2
// stopping! 1 3
- lable 在{}block中間:
function foo() {
// `bar` labeled-block
bar: {
console.log( "Hello" );
break bar;
console.log( "never runs" );
}
console.log( "World" );
}
foo();
// Hello
// World
- 關於JSON,是JS中的syntax,但不是合理的grammar
使用時,
JSON value {“a”:42} no
JSON-P foo({“a”:42}) yes
(3).Blocks
先看一個例子
[] + {}; // "[object Object]"
//[] is coerced to "" and thus {} is coerced to a string
{} + []; // 0
//{}is a block,+[] -> 0
0 + [] ; //'0'
//0 + ""
2.else if And Optional Blocks
else if is actually else {if(){}}
Operator Precedence
1.&& , || =
= > ,
var a = 42, b;
b = ( a++, a );
a; // 43
b; // 43
var a = 42, b;
b = a++, a;
a; // 43
b; // 42
== > && > || > =
true || false && false; // true
"hello world" || 10 == 10 ; //'hello world'
2.Short Circuited && || 短路
只需要判斷一半的條件
//opts 如果false,後面的就不會拋出錯誤
function doSomething(opts) {
if (opts && opts.cool) {
// ..
}
}
3.&& > || > ?:
a && b || c ? c || b ? a : c && b : a
is equal to
(a && b || c) ? (c || b) ? a : (c && b) : a
((a && b) || c) ? ((c || b) ? a : (c && b)) : a
4.Associativity 多個一樣的算子
right/left-associativity:
1.&&,||結果一樣,方向從左到右
2.? :grouping方向從右到左
a ? b : c ? d : e;
結果是a ? b : (c ? d : e)
3.= 也是right-associativity
var a, b, c;
a = b = c = 42;
//a = (b = (c = 42))
Automatic Semicolons自動加;
1.ASI (Automatic Semicolon Insertion)
(1).JS parsesr在碰到某些statement末尾的空白/comments會自動插入;
var a = 42, b
c;
//equal to
var a = 42,b;
c; // throw a error
(2).碰到break,continue,return,yield時
function foo(a) {
if (!a) return
a *= 2;
// ..
}
Errors
很多errors,發生時間:compile/runtime time
var a = /+foo/; // Error!
function bar(a,b,a) { "use strict"; } // Error!
2.Using Variables Too Early
ES6 define TDZ (“Temporal Dead Zone”).
//var不會出錯
{
a = 2; // ReferenceError!
let a;
}
{
typeof a; // undefined
typeof b; // ReferenceError! (TDZ)
let b;
}
Function Arguments
1.ES6 default parameter values
var b = 3;
function foo( a = 42, b = a + b + 5 ) {
console.log(a,b)
}
foo() // error! b is not defined
如果你省略了參數或者傳入undefined,就用default value
function foo( a = 42, b = a + 1 ) {
console.log( a, b );
}
foo(); // 42 43
foo( undefined ); // 42 43
foo( 5 ); // 5 6
foo( void 0, 7 ); // 42 7
foo( null ); // null 1 null => 0
2.arguments 與命名參數
a的指針指向傳入的參數,
//非嚴格模式下
//同時refer to arguments[]與a,會綁定他們
function foo(a) {
a = 42;
console.log( arguments[0] );
}
foo( 2 ); // 42 (linked)
foo(); // undefined (not linked)
function foo(a) {
"use strict";
a = 42;
console.log( arguments[0] );
}
foo( 2 ); // 2 (not linked)
foo(); // undefined (not linked)
try..finally
捕獲runtime error
1.try catch/finally(二者可以一起存在)
finally{}裏的Code,一定會運行的,
right after try(catch)完成
function foo() {
try {
return 42;
}catch(e){
//..
}
finally {
console.log( "Hello" );
}
console.log( "never runs" );
}
console.log( foo() );
// Hello 在try完成後運行
// 42 在foo完成後,console.log(42)
2.如果finally裏thorw一個exception,
那麼try裏的value會被捨棄
function foo() {
try {
return 42;
}
finally {
throw "Oops!";
}
console.log( "never runs" );
}
console.log( foo() );
// Uncaught Exception: Oops!
3.finally裏的return會override try裏面的
function baz() {
try {
return 42;
}
finally {
// override previous `return 42`
return "Hello";
}
}
baz(); // "Hello"
Switch
普通的
switch (a) {
case 2:
// do something
break;
case 42:
// do another thing
break;
default:
// fallback to here
升級
var a = "42";
switch (true) {
case a == 10:
console.log( "10 or '10'" );
break;
case a == 42:
console.log( "42 or '42'" );
break;
default:
// never gets here
}
// 42 or '42'