一、常見的原生函數有:正則表達式
二、全部typeof返回值爲"object"的對象(如數組)都包含一個內部屬性[Class]。咱們能夠經過Object.prototype.toString()來查看。(對象的內部[[Class]]屬性和建立該對象的內建原生構造函數相對應)數組
Object.prototype.toString.call([1,2,3]) // "[object Array]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
複製代碼
三、若是想要自行封裝基本類型值,可使用Object()
函數(不帶new關鍵字)安全
var a = "abc";
var b = new String(a);
var c = Object(a);
typeof a; // "string"
typeof b; // "object"
typeof c; // "object"
b instanceof String // true
c instanceof String // true
Object.prototype.toString.call(b) // "[object String]"
Object.prototype.toString.call(c) // "[object String]"
複製代碼
四、若是想要獲得封裝對象中的基本類型值
,可使用valueOf()
函數。bash
var a = new String('abc');
var b = new Number(42);
var c = new Boolean(true);
var d = a + ""; // 隱式拆封
a.valueOf() // "abc"
b.valueOf() // 42
c.valueOf(); // true
typeof d // "string"
複製代碼
五、Array構造函數只帶一個數字
參數的時候,該參數會被做爲數組的預設長度
,而非只充當數組中的一個元素
。函數
var a = new Array(1,2,3)
a // [1,2,3]
複製代碼
六、咱們將包含至少一個"空單元"
的數組稱爲稀疏數組
。ui
七、建立數組的不一樣的方式會有所區別this
var a = new Array(3);
var b = [undefined,undefined,undefined]
a.join("-"); // "--"
b.join("-"); // "--"
a.map(function(v,i){return i}); // [undefined * 3]
b.map(function(v,i){return i}); // [0,1,2]
function fakeJoin(arr,connector){
var str = "";
for(var i = 0;i<arr.length;i++){
if(i>0){
str += connector
}
if(arr[i]!==undefined){
str += arr[i]
}
}
return str;
}
複製代碼
八、new Object() 能夠建立對象,可是沒法像常量形式那樣一次設定多個屬性。new Function() 好比動態定義函數參數
和函數體
的時候能夠建立函數。 new RegExp() 能夠動態定義正則表達式
。spa
var c = new Object();
var e = new Function("a","return a*2;") // 至關於var f = function(a){return a * 2}
var name = 'xxx'
var namePattern = new RegExp("\\b(?:"+name+")+\\b","ig");
var matches = someText.match(namePattern)
複製代碼
九、Symbolprototype
Symbol.create
、Symbol.iterator
// 能夠自定義對象的迭代器,for..of能夠遍歷值
obj[Symbol.iterator] = function(){}
複製代碼
var mysym = Symbol('symbol')
mysym // Symbol(symbol)
mysym.toString() //"Symbol(symbol)"
typeof mysym // "symbol"
var a = {}
a[mysym] = 'foobar'
Object.getOwnPropertySymbols(a) // [Symbol(symbol)]
複製代碼
一、將值從一種類型轉換爲另外一種類型一般稱爲類型轉換
,這是顯式的狀況;隱式的狀況稱爲強制類型轉換
。code
二、Javascript中的強制類型轉換老是返回標量基本類型值
,如字符串、數字和布爾值,不會返回對象和函數。
三、類型轉換髮生在靜態類型語言的編譯階段
,而強制類型轉換髮生在動態類型語言的運行時(runtime)
一、抽象操做ToString,它負責處理非字符串到字符串的強制類型轉換。null轉換爲"null",undefined轉換爲"undefined",true轉換爲"true"。
二、對普通對象
來講,除非自行定義,不然toString()返回內部屬性
[[class]]的值,如"[object Object]"
三、若是對象有本身的toString()方法,字符串化時就會調用該方法並使用其返回值。
四、數組
的默認toString()方法通過了從新定義,將全部單元字符串化之後在用,鏈接起來
。
var a = [1,2,3]
a.toString(); // "1,2,3"
複製代碼
一、JSON字符串化(JSON.stringify)並不是嚴格意義上的強制類型轉換。安全的JSON值均可以使用JSON.stringify字符串化。安全的JSON值是指可以呈現爲有效的JSON格式的值。
二、不安全的JSON值:
三、JSON.stringify()在對象
中遇到undefined、function和symbol時會自動將其忽略
。在數組
中則會返回null
(以保證單元位置不變)。對包含循環引用的對象執行JSON.stringify()會出錯。
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()
方法,JSON字符串化時會首先調用該方法,而後用它的返回值
來進行序列化
。(若是含有非法JSON值的對象作字符串化,或者對象中的某些值沒法序列化時,就須要定義toJSON()方法來返回一個安全的JSON值
)
var o = {}
var a = {
b:41,
c:o,
d:function(){}
}
// 循環引用
o.e = a;
JSON.stringify(a) // 產生錯誤
a.toJSON = function(){
// 序列化僅包含b
return {b:this.b}
}
JSON.stringify(a) // "{"b":42}"
複製代碼
五、toJSON() 返回的應該是一個適當的值,能夠是任何類型
,而後在由JSON.stringify()對其進行字符串化。(也就是說返回一個可以被字符串化的安全的JSON值
,而不是返回一個JSON字符串
)
var a = {
val:[1,2,3],
toJSON:function(){
return this.val.slice(1);
}
}
JSON.stringify(a); // "[2,3]"
複製代碼
六、能夠向JSON.stringify()傳遞一個可選參數replacer,它能夠是數組
或者函數
。用來指定對象序列化過程當中哪些屬性應該會處理
,哪些應該被排除,和toJSON很像。
字符串數組
,其中包含序列化要處理的對象的屬性名稱
。鍵
和值
。若是要忽略某個鍵就返回undefined
,不然返回指定的值。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]}"
複製代碼
縮進格式
。space爲正整數
時是指定每一級縮進的字符數
,還能夠是字符串
,此時最前面的十個字符
被用於每一級的縮進。(感受沒啥大用)一、true轉換爲1,false轉換爲0。undefined轉換爲NaN,Null轉換爲0。
二、對象(包含數組)轉換爲基本的類型值,會按照以下規則:
而且返回基本類型值
,就使用該值進行強制類型轉換。三、使用Object.create(null)
建立的對象[[Prototype]]屬性爲null,而且沒有valueOf和toString方法,所以沒法進行強制類型轉換
。
一、如下這些是假值:
二、假值對象(瞭解如下吧)
document.all
一、字符串=>數字
二、數字=>字符串
var a = 42;
var b = a.toString()
var c = "3.14"
var d = +c;
b // "42"
d // 3.14
複製代碼
三、一元運算符+的另外一個常見用途是將日期(Date)對象強制類型
轉換爲數字
,返回結果爲Unix時間戳,以毫秒爲單位。
var d = +new Date()
d // 1560354322864
// 別的方式獲取時間戳
var timestamp = new Date().getTime()
// Date.now
if(!Date.now){
Date.now = function(){
return +new Date();
}
}
複製代碼
一、parseInt解析容許字符串中含有非數字字符
,解析從左到右的順序,若是遇到非數字字符就中止。而轉換不容許出現非數字字符,不然會失敗並返回NaN。(解析浮點數可使用parseFloat())
var a = "42"
var b = "42px"
Number(a) // 42
parseInt(b) // 42
複製代碼
二、早期版本的parseInt()有一個問題,若是沒有第二個參數來指定的基數,parseInt會根據字符串的第一個字符來自行決定基數
。若是第一個字符是x或X,則轉換爲十六進制數字。若是是0,則轉換爲八進制數字。(注意ES5以後默認轉換爲十進制數。若是第二個參數不傳或者false值,按照十進制處理。)
一、一元運算符 ! 顯式地將值強制類型轉換爲布爾值。可是它同時還將 真值反轉爲假值(或者將假值反轉爲真值)。因此顯式強制類型轉換爲布爾值最經常使用的方法是 !!,由於第二個 ! 會將結果反轉回原值。
一、根據 ES5 規範 11.6.1節,若是某個操做數是字符串
或者可以經過如下步驟轉換爲字符串
的話,+ 將進行拼接操做
。若是其中一個操做數是對象(包括數組),則首先對其調用 ToPrimitive 抽象操做(規範 9.1 節),該抽象操做再調用 [[DefaultValue]](規範 8.12.8 節),以數字做爲上下文。 二、若是 + 的其中一個操做數是字符串
(或者經過以上步驟能夠獲得字符串), 則執行字符串拼接;不然執行數字加法。
var a = [1,2];
var b = [3,4];
a + b; // "1,23,4"
複製代碼
三、咱們能夠將數字
和空字符串 ""
相 + 來將其轉換爲字符串
var a = 42;
var b = a + "";
b; // "42"
複製代碼
四、a + ""(隱式)和前面的String(a)(顯式)之間有一個細微的差異須要注意。根據 ToPrimitive抽象操做規則,a + ""會對a調用valueOf()方法
,而後經過ToString
抽象 操做將返回值轉換爲字符串
。而 String(a) 則是直接調用 ToString()
。
var a = {
valueOf: function() { return 42; },
toString: function() { return 4; }
};
a + ""; // "42"
String( a ); // "4"
複製代碼
五、-是數字減法運算符,所以a - 0會將a強制類型轉換爲數字。也可使用a * 1和a / 1。
var a = "3.14";
var b = a - 0;
b; // 3.14
var a = [3];
var b = [1];
a - b; // 2
複製代碼
一、可使用!!來將值轉換爲布爾值,再經過 Number(..) 顯式強制類型轉換爲 0 或 1。
一、下面的狀況會發生 布爾值隱式強制類型轉換:
一、&& 和 || 運算符的返回值並不必定是布爾類型,而是兩個操做數其中一個的值。 二、使用|| 和 &&注意如下幾點:
var a = 42;
var b = "abc";
var c = null;
a || b; a && b;
c || b; c && b;
// 42
// "abc"
// "abc"
// null
複製代碼
一、ES6 容許 從符號到字符串的顯式強制類型轉換,然而隱式強制類型轉換會產生錯誤。 二、符號不可以被強制類型轉換爲數字(顯式和隱式都會產生錯誤),但能夠被強制類型轉換 爲布爾值(顯式和隱式結果都是 true)
var s1 = Symbol( "cool" );
String( s1 ); // "Symbol(cool)"
var s2 = Symbol( "not cool" );
s2 + ""; // TypeError
複製代碼
一、常見的誤區是「== 檢查值是否相等,=== 檢查值和類型是否相等」。正確的解釋是:「== 容許在相等比較中進行強制類型轉換
,而 === 不容許。」
一、字符串
和數字
之間的相等比較
ES5 規範 11.9.3.4-5 這樣定義:
var a = 42;
var b = "42";
a === b; // false 不進行強制類型轉換比較
a == b; // true 進行強制轉換後進行比較
複製代碼
二、其餘類型和布爾類型之間的相等比較
ES5 規範 11.9.3.6-7 這樣定義:
var a = "42";
var b = true;
a == b; // false
複製代碼
三、null 和 undefined 之間的相等比較
ES5 規範 11.9.3.2-3 這樣定義:
在 == 中 null 和 undefined 相等(它們也與其自身相等),除此以外其餘值都不存在這種 狀況
。
var a = null;
var b;
a == b; // true
a == null; // true
b == null; // true
a == false; // false
b == false; // false
a == ""; // false
b == "";// false
a == 0;// false
b == 0;// false
複製代碼
四、對象和非對象之間的相等比較
ES5 規範 11.9.3.8-9 這樣定義:
var a = 42;
var b = [ 42 ];
a == b; // true
var a = 'abc'
var b = Object(a)
a===b // false
a==b // true
複製代碼
五、極端狀況
[] == ![] // true
複製代碼
讓咱們看看 ! 運算符都作了些什麼?根據 ToBoolean 規則,它會進行布爾 值的顯式強制類型轉換(同時反轉奇偶校驗位)。因此[] == ![]變成了[] == false。 []=>''=>0,而false=>0 ,因此兩邊天然就相等了。
ES5 規範 11.8.5 節定義:
一、比較雙方首先調用 ToPrimitive,若是結果出現非字符串,就根據 ToNumber 規則將雙方強 制類型轉換爲數字來進行比較。(感受這個有點問題)
var a = [ 42 ];
var b = [ "43" ];
a < b; // true
b < a; // false
複製代碼
二、若是比較雙方都是字符串,則按字母順序來進行比較
var a = [ "42" ];
var b = [ "043" ];
a < b; // false
複製代碼
三、下面的例子有點奇怪
var a = { b: 42 };
var b = { b: 43 };
a < b; // false
a == b; // false 對象比較 值不一樣直接是false
a > b; // false
a <= b; // true
a >= b; // true
複製代碼
規範規定,<= 應該是「小於或者等於」。實際上 JavaScript 中 <= 是 「不大於」的意思(即 !(a > b),處理爲 !(b < a))。同理 a >= b 處理爲 b <= a