必讀:html
JavaScript築基篇(二)->JavaScript數據類型segmentfault
深刻理解JavaScript系列(12):變量對象(Variable Object)函數
基本數據類型(其實也統稱爲基本型或原始型)this
undefined,null,number,boolean,stringspa
一種複雜數據類型(引用型)prototype
Object指針
undefined 類型:聲明未定義日誌
let a a === undefined // true
null 類型:null值表示一個空指針,初始化空對象可賦值爲null
console.log(undefined == null); // true console.log(undefined === null); // false
boolean 類型:只有兩個字面值true false
。可是這兩個值和數字值不是一回事,所以true
不必定等於1,而false
也不必定等於0。
要將一個值轉爲boolean
型等價的值,有兩種方案:
一種是顯式轉換-調用類型轉換函數Boolean()
一種是自動轉換-如if(value)中的value就會自動轉化成爲boolean值
轉換爲true的值 | 轉換爲false的值 | |
---|---|---|
boolean | true | false |
string | 任何非空字符串 | "" (空字符串) |
bumber | 任何非零數字值(包括無窮大) | 0和NaN |
undefined | 無 | undefined |
null | 無 | null |
Object | 任何對象 | 無 |
number 類型:
表示整型,浮點型和NaN
在JS
中,0/0、NaN/0
會返回NaN
,其它數字/0
會返回Infinity
,不會報錯。
isNaN()
console.log(NaN + 1); // NaN,任何涉及到NaN的操做都會返回NaN console.log(NaN === NaN); // false,NaN與任何值都不相等,包括NaN自己 console.log(isNaN(NaN)); // true,是NaN console.log(isNaN('10')); // false,被轉爲數字10 console.log(isNaN(true)); // false,被轉爲數字1 console.log(isNaN(null)); // false,被轉爲數字0 console.log(isNaN(undefined)); // true,返回NaN console.log(isNaN('hello')); // true,沒法轉換爲數字 console.log(0/0);// NaN,0/0返回NaN console.log(NaN/0);// NaN,NaN/0返回NaN console.log(1/0);// Infinity,其它數字/0返回Infinity console.log('1'/0);// Infinity,'1'成功轉爲數字 console.log('1a'/0);// NaN,'1a'轉爲數字失敗,變爲NaN console.log(Infinity/0);// Infinity,其它數字/0返回Infinity
注意:Infinity的類型是Number(不是基礎數據類型)
有兩種方法能夠將非number類型的值轉換爲number類型
一種是顯示轉換-調用Number()、parseInt()、parseFloat()
方法轉換
Number():
若是是boolean值,true和false將分別被替換爲1和0
若是是數字值,只是簡單的傳入和返回
若是是null值,返回0
若是是undefined,返回NaN
若是是字符串,遵循下列規則:
若是字符串中只包含數字,則將其轉換爲十進制數值,即」1「會變成1,」123「會變成123,而」011「會變成11(前導的0被忽略)
若是字符串中包含有效的浮點格式,如」1.1「,則將其轉換爲對應的浮點數(一樣,也會忽略前導0)
若是字符串中包含有效的十六進制格式,例如」0xf「,則將其轉換爲相同大小的十進制整數值
若是字符串是空的,則將其轉換爲0
若是字符串中包含除了上述格式以外的字符,則將其轉換爲NaN
若是是對象,則調用對象的valueOf()方法,而後依照前面的規則轉換返回的值。若是轉換的結果是NaN,則調用對象的toString()方法,而後再依次按照前面的規則轉換返回的字符串值。
console.log(Number(''));//0 console.log(Number('a'));//NaN console.log(Number(true));//1 console.log(Number('001'));//1 console.log(Number('001.1'));//1.1 console.log(Number('0xf'));//15 console.log(Number('000xf'));//NaN var a = {}; // 調用對象的valueOf()方法 console.log(Number(a));//NaN a.toString = function(){return 2}; // 重寫valueOf()方法 console.log(Number(a));//2 a.valueOf = function(){return 1}; console.log(Number(a));//1
parseInt():
經常用於將其它類型值轉化爲整形。parseInt轉換與Number()有區別,具體規則以下:
parseInt(value,radius)有兩個參數,第一個參數是須要轉換的值,第二個參數是轉換進制(該值介於 2 ~ 36 之間。若是該參數小於 2 或者大於 36,則 parseInt() 將返回 NaN。),若是不傳(或值爲0),默認以10爲基數(若是value以 「0x」 或 「0X」 開頭,將以 16 爲基數)
注意在第二個參數默認的狀況下,若是須要轉換的string值以0開頭,如'070',有一些環境中,會自動轉化爲8進制56,有一些環境中會自動轉化爲10進制70。因此爲了統一效果,咱們在轉換爲10進制時,會將第二個參數傳10
console.log(parseInt(''));//NaN console.log(parseInt('a'));//NaN console.log(parseInt('1234blue'));//1234 console.log(parseInt(true));//NaN console.log(parseInt('070'));//70,可是有一些環境中會自動轉換爲8進制56 console.log(parseInt('070',8));//56 console.log(parseInt('001.1'));//1 console.log(parseInt('0xf'));//15,16進制 console.log(parseInt('AF',16));//175,16進制 console.log(parseInt('AF'));//NaN console.log(parseInt('000xf'));//0 var a = {}; console.log(parseInt(a));//NaN a.toString = function(){return 2}; // 重寫valueOf()方法 console.log(parseInt(a));//2 a.valueOf = function(){return 1}; // 重寫valueOf()方法 console.log(parseInt(a));//2
parseFloat():
parseFloat()
轉換規則基本與parseInt()
一致,只有以下不一樣點
parseFloat()遇到浮動數據時,浮點有效(可是隻有第一個.有效),如"10.1"會被轉爲10.1;'10.1.1'會被轉爲10.1
console.log(parseFloat('1234blue'));//1234 console.log(parseFloat('1234blue',2));//1234 console.log(parseFloat('0xA'));//0 console.log(parseFloat('10.1'));//10.1 console.log(parseFloat('10.1.1'));//10.1 console.log(parseFloat('010'));//10
因爲Number()函數在轉換字符串時比較複雜並且不夠合理,所以在處理整數的時候更經常使用的是parseInt()函數-需注意最好第二個參數傳10,處理浮點數時更經常使用parseFloat()
var a=10.2; var b= 10.1; console.log(a - b === 0.1);//false console.log(a - 10.1 === 0.1);//false,實際是0.09999999999999964 console.log(a - 0.1 === 10.1);//true
string:
string類型用於表示由零或多個16位Unicode字符組成的字符序列,即字符串。字符串能夠由單引號(')或雙引號(")表示。任何字符串的長度均可以經過訪問其length屬性取得。
要把一個值轉換爲一個字符串有三種方式。
第一種是使用幾乎每一個值都有的toString()
方法(除去null和undefined
沒有)
toString(radius)
有一個參數-基數,當須要toString
的值爲number
時,參數能夠生效(能夠轉換爲對應進制輸出,如10.toString(8)
輸出爲12。
第二種是隱式轉換,好比字符串+ number(null,undefined,object等),會默認轉爲字符串(若是後面相加的是object對象,會返回object對象的toString或valueOf值)
第三種是經過轉換函數String()
,轉換規則以下
若是值有toString()
方法,則調用該方法(沒有參數)並返回相應的結果(注意,valueOf()
方法沒用)
若是值是null
,則返回null
若是值是undefined
,則返回undefined
var a = 10; console.log(a.toString());//10 console.log(a.toString(8));//12 var b = '10' console.log(b.toString(8));//10,字符串基數沒用 var c = {}; console.log(c);//[object Object] console.log(c + '1');//[object Object]1 console.log(String(c));//[object Object] c.valueOf = function () { return '重寫c的valueOf方法' }; console.log(c);// {valueOf: ƒ} valueOf重寫 console.log(c + '1');// 重寫c的valueOf方法1 隱式轉換時,valueOf起做用了 console.log(String(c));// [object Object] c.toString = function () { return '重寫c的toString方法' }; console.log(c);// {valueOf: ƒ, toString: ƒ} toString起做用了 console.log(String(c)); // 重寫c的toString方法 console.log(String(null));// null,null和undefined能夠String()輸出 console.log(String(undefined));// undefined ,null和undefined能夠String()輸出 // console.log(null.toString());//報錯,null和undefined不能toString let d = {} d.valueOf = function () { console.log('valueOf 執行了') return 'valueOf' }; d.toString = function () { console.log('toString 執行了') return 'toString' }; console.log(d + '1') // 隱式轉換 valueOf 執行了 console.log(String(d)) // String toString 執行了
object 類型:
Object的每一個實例都具備下列屬性和方法:
constructor
——保存着用於建立當前對象的函數
hasOwnProperty(propertyName)
——用於檢查給定的屬性在當前對象實例中(而不是在實例的原型中)是否存在。其中,做爲參數的屬性名(propertyName)
必須以字符串形式指定(例如:o.hasOwnProperty("name")
)
isPrototypeOf(object)
——用於檢查傳入的對象是不是另外一個對象的原型
propertyIsEnumerable(propertyName)
——用於檢查給定的屬性是否可以使用for-in語句來枚舉
toString()
——返回對象的字符串表示
valueOf()
var obj = new Object(); obj.name = 'zs'; obj.sayHi = function () { console.log('Hi'); } console.log(obj.hasOwnProperty('a')); // 實例對象 true console.log(obj.hasOwnProperty('sayHi')); // 實例對象 true console.log(obj); // 實例對象 console.log(obj.constructor); // 構造函數Object() console.log(obj.__proto__); // 原型
valueOf()
和toString()
valueOf
方法返回指定對象的原始值。
toString
: 返回對象的字符串表示
valueOf
轉換規則MDN對valueOf()的描述
JavaScript調用valueOf
方法將對象轉換爲原始值。你不多須要本身調用valueOf
方法;當遇到要預期的原始值的對象時,JavaScript會自動調用它。
默認狀況下,valueOf
方法由 Object
後面的每一個對象繼承。 每一個內置的核心對象都會覆蓋此方法以返回適當的值。若是對象沒有原始值,則valueOf
將返回對象自己。
JavaScript的許多內置對象都重寫了該函數,以實現更適合自身的功能須要。所以,不一樣類型對象的valueOf()
方法的返回值和返回值類型都可能不一樣。
非原始值(也就是對象)重寫規則以下:
對象 | valueOf返回值 |
---|---|
Array | 數組自己 |
Boolean | 布爾值 |
Date | 返回毫秒形式的時間戳 |
Function | 函數自己 |
Number | 數字值 |
Object | 對象自己 |
String | 字符串值 |
// Array:返回數組對象自己 var array = ["ABC", true, 12, -5]; console.log(array.valueOf() === array); // true // Date:當前時間距1970年1月1日午夜的毫秒數 var date = new Date(2013, 7, 18, 23, 11, 59, 230); console.log(date.valueOf()); // 1376838719230 // Number:返回數字值 var num = 15.26540; console.log(num.valueOf()); // 15.2654 // 布爾:返回布爾值true或false var bool = true; console.log(bool.valueOf() === bool); // true // new一個Boolean對象 var newBool = new Boolean(true); // valueOf()返回的是true,二者的值相等 console.log(newBool.valueOf() == newBool); // true // 可是不全等,二者類型不相等,前者是boolean類型,後者是object類型 console.log(newBool.valueOf() === newBool); // false // Function:返回函數自己 function foo(){} console.log( foo.valueOf() === foo ); // true var foo2 = new Function("x", "y", "return x + y;"); console.log( foo2.valueOf() ); /* ƒ anonymous(x,y) {return x + y;} */ // Object:返回對象自己 var obj = {name: "張三", age: 18}; console.log( obj.valueOf() === obj ); // true // String:返回字符串值 var str = "http://www.xyz.com"; console.log( str.valueOf() === str ); // true // new一個字符串對象 var str2 = new String("http://www.xyz.com"); // 二者的值相等,但不全等,由於類型不一樣,前者爲string類型,後者爲object類型 console.log( str2.valueOf() === str2 ); // false
直接轉換爲true(包裝類型也同樣),不調用valueOf和toString
在預期會將對象用做數字使用時,好比參與算術運算等等操做,對象轉換爲數字會依次調用valueOf和toString方法,具體規則以下:
若是對象具備valueOf
方法且返回原始值(string、number、boolean、undefined、null),則將該原始值轉換爲數字(轉換失敗會返回NaN),並返回這個數字
若是對象具備toString
方法且返回原始值(string、number、boolean、undefined、null),則將該原始值轉換爲數字(轉換失敗會返回NaN),並返回這個數字
轉換失敗,拋出TypeError
若是對象具備toString
方法且返回原始值(string、number、boolean、undefined、null),則將該原始值轉換爲字符串,並返回該字符串
若是對象具備valueOf
方法且返回原始值(string、number、boolean、undefined、null),則將該原始值轉換爲字符串,並返回該字符串
轉換失敗,拋出TypeError
toString
轉換規則對象 | toString返回值 |
---|---|
Array | 以逗號分割的字符串,如[1,2]的toString返回值爲"1,2" |
Boolean | "True" |
Date | 可讀的時間字符串,如"Tue Oct 15 2019 12:20:56 GMT+0800 (中國標準時間)" |
Function | 聲明函數的JS源代碼字符串 |
Number | "數字值" |
Object | "[object Object]" |
String | "字符串" |
toString()
方法返回指定的布爾對象的字符串形式
let flag = new Boolean(true); console.log(flag.toString()) // true let flag1 = new Boolean(1); console.log(flag1.toString()) // true
toString()
返回一個字符串,表示指定的數組及其元素。
let array = ['abc', true, 12, undefined, 'ok'] console.log(array.toString()); // abc,true,12,,ok
toString()
方法返回一個表示當前函數源代碼的字符串。
function fun(num) { num += 5 } console.log(fun.toString()); /** * function fun(num) { num += 5 } */
toString()
let obj = { name: 'houfee'} console.log(obj.toString()); // [object Object]
// 保存原始的valueOf var valueOf = Object.prototype.valueOf; var toString = Object.prototype.toString; // 添加valueOf日誌 Object.prototype.valueOf = function () { console.log('valueOf'); return valueOf.call(this); }; // 添加toString日誌 Object.prototype.toString = function () { console.log('toString'); return toString.call(this); }; var a = {}; var b = new Boolean(false); if (a) { console.log(1); } if (b) { // console.log(typeof b); // console.log(b); console.log(2); }
// 保存原始的valueOf var valueOf = Object.prototype.valueOf; var toString = Object.prototype.toString; // 添加valueOf日誌 Object.prototype.valueOf = function () { console.log('valueOf'); return valueOf.call(this); }; // 添加toString日誌 Object.prototype.toString = function () { console.log('toString'); return toString.call(this); }; var a = {}; console.log(++a); // valueOf toString NaN
valueOf方法返回的是對象自己,不是原始值,繼續執行
toString方法返回的是"[object Object]",是原始值(字符串),將字符串轉換爲數字NaN
// 保存原始的valueOf var valueOf = Object.prototype.valueOf; var toString = Object.prototype.toString; // 添加valueOf日誌 Object.prototype.valueOf = function () { console.log('valueOf'); return "1"; // 強制返回原始值 }; // 添加toString日誌 Object.prototype.toString = function () { console.log('toString'); return toString.call(this); }; var a = {}; console.log(++a); // valueOf 2
在預期會將對象用做字符串時,好比一個字符串拼接了字符串,傳入了一個對象,此時會發生轉換。
// 保存原始的valueOf var valueOf = Object.prototype.valueOf; var toString = Object.prototype.toString; // 添加valueOf日誌 Object.prototype.valueOf = function () { console.log('valueOf'); return valueOf.call(this); }; // 添加toString日誌 Object.prototype.toString = function () { console.log('toString'); return toString.call(this); // '[object Object]' toString方法先調用 ,若是返回結果是字符串,則中止調用 valueOf,不是字符串,那麼就調用 valueOf }; var a = {}; console.log(a.toString()); // valueOf toString [object Object]str // alert(a) // alert主動調用toString方法,返回了字符串"[object Object]",對象最終轉換爲該字符串
// 保存原始的valueOf var valueOf = Object.prototype.valueOf; var toString = Object.prototype.toString; // 添加valueOf日誌 Object.prototype.valueOf = function () { console.log('valueOf'); return valueOf.call(this); }; // 添加toString日誌 Object.prototype.toString = function () { console.log('toString'); return this; }; var a = {}; alert(a); /* toString valueOf Uncaught TypeError: Cannot convert object to primitive value at 1.js:16 */
// 保存原始的valueOf var valueOf = Object.prototype.valueOf; var toString = Object.prototype.toString; // 添加valueOf日誌 Object.prototype.valueOf = function () { console.log('valueOf'); return valueOf.call(this); }; // 添加toString日誌 Object.prototype.toString = function () { console.log('toString'); return toString.call(this); // '[object Object]' toString方法先調用 ,若是返回結果是字符串,則中止調用 valueOf,不是字符串,那麼就調用 valueOf }; var a = {}; console.log(a + 'str'); // valueOf toString [object Object]str // alert(a) // alert主動調用toString方法,返回了字符串"[object Object]",對象最終轉換爲該字符串
let a = { name: 123 }; console.log(Number(a)); // NaN /* * JS對象強制類型轉換 * 主要調用 object.valueOf() 和 object.toString() 方法 * 1.先調用 object 的 valueOf() 方法 * 2.判斷返回值 是否爲 基礎數據類型? * 3.是!則轉換規則按照相應數據類型的規則對其進行轉換 * 4.不是!在返回值的基礎上繼續調用 toString() 方法 * 5.判斷調用 toString() 方法返回值是否爲 基礎數據類型 * 6.是!則轉換規則按照相應數據類型的規則對其進行轉換 * 7.不是!報錯: * */
a.toString = function () {return {name: 'newName'}} // 讓toString方法返回值爲 複雜數據類型 a.toString() // 調用覆蓋的方法 Number(a) // 報錯
a.toString = function () {return '321'} // 讓toString方法返回值爲 複雜數據類型 a.toString() // 調用覆蓋的方法 Number(a) // 321
因此Number強制轉換對象的過程即爲如上7步
let b = {name: 'houfee'} console.log(String(b)); // [object Object] let c = [] console.log(String(c)); // 空字符串 let d = {} console.log(String(d)); // [object Object]
判斷該方法的返回值是否爲基礎數據類型(Number,String,Boolean,Undefined,Null)
若返回值爲基礎數據類型,則轉換規則按照相應數據類型的轉換規則對其進行轉換
若返回值不爲基礎數據類型,則在該返回值的基礎上繼續調用valueOf方法
判斷valueOf的返回值是否爲基礎數據類型
判斷是否爲基礎數據類型,如果基礎數據類型則進行操做3
若仍舊不爲基礎數據類型則報錯
String與Number的區別則在於
Number是先調用valueOf()再調用toString ()
而String是先調用toString()再調用valueOf()
Number()先轉換爲原始類型,再轉化爲字符串形式
String()先轉換爲字符串形式,再轉化爲原始類型
function isArray(value) { return Object.prototype.toString.call(value) == "[object Array]" } function isFunction(value) { return Object.prototype.toString.call(value) == "[object Function]" } function isRegExp(value) { return Object.prototype.toString.call(value) == "[object RegExp]" }
console.log({}); // {} console.log(Number({})); // NaN、 console.log(String({})); // [object Object] console.log(Boolean({})); // true console.log([]); // [] console.log(Number([])); // 0 console.log(String([])); // 空字符串 console.log(Boolean([])); // true console.log({} + {}) // [object Object][object Object] console.log({} + []) // [object Object] console.log([] + {}) // [object Object] console.log([] + []) // 空字符串