原生函數 常用的原生函數 String() Number() Boolean() Array() Object() Function() RegExp() Date() Error() Symbol() 內部屬性 [Class] 所有typeof 返回值為object 的對象都包含一個內部屬性[Cl ...
原生函數
常用的原生函數
String()
Number()
Boolean()
Array()
Object()
Function()
RegExp()
Date()
Error()
Symbol()
內部屬性 [Class]
所有typeof 返回值為object 的對象都包含一個內部屬性[Class],這個屬性無法直接訪問,一般通過Object.prototype.toString(..) 來看。
例如:
Object.prototype.toString.call([1,2,3]);
// "[object Array]"
基本類型值
Object.prototype.toString.call(null);
// "[object Null]"
封裝對象包裝
由於基本類型值沒有.length 和 .toString() 這樣的屬性和方法。
封裝對象釋疑
想要自行封裝基本類型值,可以使用Object(..)(不帶new 關鍵字)
var a = "abc";
var b = new String(a);
var c = Object(a);
一般不推薦直接使用封裝函數
拆封
封裝對象中的基本類型值,可以使用valueOf() 函數。
var a = new String("abc");
var b = new Number(42);
var c = new Boolean(true);
a.valueOf(); // "abc"
b.valueOf(); // 42
c.valueOf(); // true
原生函數作為構造函數
Array(..)
var a = new Array(1,2,3);
a; // [1,2,3]
var b = [1,2,3]
b; // [1,2,3]
構造函數Array(..),不要求必須帶關鍵字new,不帶時他會自動補上Array構造函數只帶一個參數時候,該參數會被數組的預設長度而不是當數組中的一個元素。
var a = new Array(3);
a.length; // 3
a;
總之永遠不要創建和使用空單元數組
Object(..) , Function(..) , 和RegExp(..)
除非萬不得已,否則不要使用Object(..) / Function(..)/ RegExp(..)
Date(..) 和Error(..)
創建時間必須使用 new Date(),主要是用來獲取當前的Unix 時間戳Date.new()然後通過日期對象中的getTime() 來獲得。
創建錯誤對象(error objec) 主要是為了獲得當前運行的上下文。
Symbol(..)
基本數據類型——符號。符號具有唯一性的特殊值,用它來命名屬性不容易導致重名。
Symbol 的靜態屬性形式,Symbol.create, Symbol.iterator
obj[Sybol.iterator] = function() {/*..*/}
使用 Symbol(..) 原生構造函數來自定義符號,不能帶new 關鍵字,否則報錯。
var mysym = Symbol("my own symbol");
mysym; // Symbol(my own symbol)
mysym.toString(); // "Symbol(my own symbol)"
typeof mysym; // "symbol"
var a = { };
a[mysym] = "foobar";
Object.getOwnPropertySymbols(a);
// [Symbol(my own symbol)]
原型類型
原生構造函數有自己的 .prototype對象 如: Array.prototype,
String.prototype.
String#indexOf(..)
在字元串中查找指定字元串的位置。
String#charAt(..)
獲得字元串指定位置上字元
String#substr(..),String#substring(..) 和String# slice(..)
獲取字元串的指定部分
String#toUpperCase() 和 String#toLowerCase()
將字元串轉換為大寫和小寫
String#trim()
去掉字元串前後的空格,返回新的字元串
強制類型轉換
值的類型轉換
將值從一種類型轉換為另一種類型轉換,這是顯示的情況,隱式的情況通常為強制類型轉換。
JavaScript 中的類型轉換總是是返回標量基本類型。
抽象值操作
ToString
抽象操作ToString ,它負責處理非字元串到字元串的強制類型轉換數組的預設toString() 方法經過重新定義,將所有的單元字元串化以後在連接在一起。
var a = [1,2,3];
a.toString(); // "1,2,3"
JSON字元串換,
JSON.stringify(..) 在對象中遇到undefined,function 和 symbol 時會自動將其忽略,在數組中則會返回null。
例如:
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.stringify(..) 對齊進行字元串化。
ToNumber
有時候需要將非數字值當做數字來使用,比如數學運算。
true 轉為 1, false 轉換為 0 ,undefined 轉換為NaN
null 轉換為0
為了將值轉換為相應的基本類型,抽象操作ToPrimitive ,首先檢查該值是否有valueOf() 方法,如果有就用該值進行強制類型轉換。沒有就用toString()
的返回值來進行強制類型轉換。如果valueOf() 和toString() 均不會返回值就會產生TypeError 錯誤。
ToBoolean
假值:
值可以被分為以下兩類。
1.可以被強制類型轉換為false的值
2.其他(被輕質類型轉換為true的值)
以下這些是假值
undefined
null
false
+0,-0和NaN
""
假值對象:瀏覽器在某些特定情況下,在常規JavaScript語法基礎上創建了一些外來值,這些就是 “假值對象”
真值
真值就是假值列表以外的值
顯式強制類型轉換
字元串和數字之間的顯示轉換
字元串和數字之間顯示強制類型轉換是通過String(..) 和Number(..).
兩者之間的顯式強制類型轉換
var a = 42;
var b = String(a);
var c = "3.14";
var d = Number(c);
b; // "42"
d: // 3.14
還有其它方式實現字元串和數字之間的顯示轉換
var a = 42;
var b = a.toString();
var c = "3.14";
var d = +c;
b; // "42"
d: // 3.14
日期顯示轉換為數字
一元運算符+ 的另一個常見的用途是將日期對象(Date)對象強制轉換為數字。
var timestamp = +new Date();
顯式解析數字字元串
解析字元串中的數字和將字元串強制類型轉換為數字的返回結果都是數字。
例如:
var a = "42";
var b = "42px";
Number(a); // 42
parseInt(a); // 42
Number(b); // NaN
parseInt(b); // 42
解析允許字元串中含有非數字字元,解析按從左到右的順序,如果遇到非數字字元就停止。
parseInt(..) 針對的是字元串,像parseInt(..) 傳遞數字和其他類型的參數是沒用的
顯示轉換為布爾值
ToBoolean 是顯式的ToBoolean 強制類型轉換:
var a = "0";
var b = [];
var c = {};
var d = "";
var e = 0;
var f = null;
var g;
Boolean(a); // true
Boolean(b); // true
Boolean(c); // true
Boolea(d); // false
Boolea(e); // false
Boolea(f); // false
Boolea(g); // false
一元運算符!顯示地將值強制類型轉換為布爾值。
var a = "0";
var b = [];
var c = {};
var d = "";
var e = 0;
var f = null;
var g;
!!a; // true
!!b; // true
!!c; // true
!!d; // false
!!e; // false
!!f; // false
!!g; // false
隱式強制類型轉換
隱式地簡化
字元串和數字之間的隱式強制類型轉換
+運算符既能用於數字加法,也能用於字元串拼接。
var a = "42";
var b = "0";
var c= 42;
var d = 0;
a + b; // "42"
c + d; // 42
對象的 - 操作與 + 類似;
var a = [3];
var b = [1];
a - b ; // 2
布爾值到數字的隱式強制類型轉換
隱式強制類型轉換為布爾值
下麵的情況會發生隱式強制類型轉換
1.if(..) 語句中的條件判斷表達式。
2.for(..;...;..)語句中的條件判斷表達式(第二個)
3.while(..) 和do..while(..) 迴圈中的條件判斷表達式。
4.? : 中的條件表達式
5.邏輯運算符 || (邏輯或) 和 (邏輯與) 左邊的操作數(作為條件判斷表達式)
|| 和 &&
|| 和 && 運算符 的返回值並不一定是布爾類型,而是兩個操作數其中的一個的值
var a = 42;
var b = "abc";
var c = null;
a || b; // 42
a && b; // "abc"
c || b; // "abc"
c&& b; // null
對於 || 來說 如果條件判斷結果為true 就返回第一個數的值,如果為false 就返回第二個操作數。
&& 則相反。
下麵是一個|| 十分常見的 || 用法。
function foo(a,b){
a = a || "hello";
b = b || "world";
console.log(a + " " + b );
}
foo(); // "hello world"
foo("yeah","yeah"); // "yeah yeah"
符號的強制類型轉換
寬鬆相等和嚴格相等
“== 允許在相等比較中進行強制類型轉換, 而=== 不允許”
抽象相等
有幾個非常規的需要註意
NaN 不等於NaN
+0 等於-0
寬鬆不相等 != 就是==的相反, !== 同理
字元串和數字之間的相等比較
1.如果Type(x) 是數字,Type(y)是字元串,則返回 x== ToNumber(y)
的結果。
2.如果Type(x) 是字元串,Type(y) 是數字,則返回 ToNumber(x)== y 的結果。
其他類型和布爾類型之間的相等比較
== 最容易出錯的地方就是true 和 false 與其他類型之間的相等比較
var a = "42";
var b = true;
a == b; // false
1.如果Type(x) 是布爾類型,則返回ToNumber(x) == y 的結果
2.如果Type(y) 是布爾類型,則返回 x == ToNumber(y) 的結果
首先:
var x = true;
var y = "42";
x == y; // false
反過來
var x = "42";
var y = false;
x == y; // false
null 和undefined 之間的相等比較
null 和undefinded 之間的 == 也涉及隱士強制類型轉換。
1.如果 x 為 null ,y 為 undefined ,則結果為 true
2.如果x 為undefined, y 為 null, 則結果為 true
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
對象和非對象之間的相等比較
關於對象和(對象/函數/ 數組) 和標量基本類型(字元串/數字/布爾值)之間的比較。
1.如果Type(x) 是字元串或數字,type(y)是對象,則返回 x == ToPrimitive(y) 的結果
2.如果Type(x) 是對象, Type(y)是字元串或數字,則返回
ToPromitive(x) == y 的結果。
var a = 42;
var b = [42];
a == b; // true
var a = "abc";
var b = Object(a); // new String(a) 一樣
a === b; // false
a == b; // true
a == b 結果為true,應為b 通過ToPromitive 進行強制類型轉換,並返回基本類型值 “abc”,與 a 相等。
假值相等的比較
一下是常規和非常規的比較
"0" == null; // false
"0" == undefined; // false
"0" == false; // true -- 暈!
“0” == NaN; // false
"0" == 0; // true
"0" == ""; // false
false == null; // false
false == undefined; // false
false == NaN; // false
false == 0; // true -- 暈!
false == "" // true -- 暈!
false == [] // true -- 暈!
false == {} // false
"" == null; // false
"" == undefined; // false
"" == NaN; // false
"" == 0; // true -- 暈!
"" == []; // true -- 暈!
"" == {}; // false
0 == null; // false
0 == undefined; // false
0 == NaN; // false
0 == []; true -- 暈!
0 == {}; false
因為他們屬於假陽。
極端情況
[] == ![] // true
對布爾值進行強制類型轉換 [] == ![] 變成 [] == false,
2 == [2]
"" == [null]; //true
42 == "43" // false
"foo" == 42; // false
"true" = '"" // false
42 == "42" // true
"foo" == ["foo"] // true
安全運用隱式強制類型轉換
1.如果兩邊的值中有true 或者 false, 千萬不要使用 ==.
2.如果兩邊的之中有[],"" 或者 0 ,儘量千萬不要使用==.這時候最好使用 === 來避免強制類型的轉換。
抽象關係比較
雙方都是字元串比較
var a = ["42"];
var b = ["043"];
a < b; // false
a 和b 並沒有被準換為數字,因為ToPrimitive 返回的是字元串,
比較的是 "42 " 和 "043" 兩個字元串, 因為"0"在字母順序上小於
“4”,所以最後結果為 false.
同理
var a = [4,2];
var b = [0,4,3];
a < b; // false
a 被轉為 “4,2”,b 轉為 “0,4,3” 同樣式按字母順序進行比較的。
var a = {b: 42};
var b = {b:43};
a < b ; // false
a 是 [object Object], b也是 [object Object] 所以按著字母順序
a < b 不成立。
下麵的例子
var a = {b: 42};
var b = {b:43};
a < b; // false
a == b; // false
a > b; // false
a <= b; // true
a >= b; // true