從toString()方法到Object.prototype.toString.call()方法
阿新 • • 發佈:2018-07-03
多層 對象 == 上下文 原生 原型繼承 null 之一 我們
第一種:用typeof判斷
我們知道typeof可以檢測數據類型,對變量或值調用typeof運算符將返回下列值之一:
undefined->Undefined
boolean->Boolean
number->Number
string->String
object->是引用類型或null類型。
function->function函數
typeof檢測引用類型或null是不能準確區分arr json等引用類型的。
那我們還知道一種檢測方式instanceof,來檢測某個對象是不是另一個對愛心那個的實例
第二種:用instanceof判斷
instanceof運算符用來測試一個對象在其原型鏈中是否存在一個構造函數的prototype屬性。
主要用來檢測引用類型,判斷Array和RegExp,無法準確判斷Function.
console.log([] instanceof Array) //true
console.log({} instanceof Object) //true
console.log(/\d/ instanceof RegExp) //true
console.log(function(){} instanceof Object) //true
console.log(function(){} instanceof Function) //true
console.log(‘‘ instanceof String) //false
console.log(1 instanceof Number) //false
var a=new Array();
alert(a instanceof Array);
同時alert(a instanceof Object)也會返回true,因為Array是object的子類。
function test(){}
var a=new test();
alert(a instanceof test);會返回true.
alert(a==b) //false;
另外,更重要的一點是instanceof可以在繼承關系中用來判斷一個實例是否屬於他的父類型。
function Foo(){}
Foo.prototype=new Aoo() //js原型繼承
var foo= new Foo();
console.log(foo instanceof Foo) //true
console.log(foo.instanceof Aoo) //true
上面代碼中是判斷了一層繼承關系的父類,在多層繼承關系中,isntanceof運算符同樣適用。
//定義構造函數
function C(){}
function D(){}
var o=new C();
o instanceof C //true
o instanceof D //false 因為D.prototype不在o的原型鏈上
o instanceof Object //true 因為Object.prototype.isPrototypeOf(o) 返回true
C.prototype instanceof Object //true 同上
C.prototype={}
var o2=new C();
o2 instanceof C //true
o instanceof C //false C。prototype指向了一個空對象,這個空對象不在o的原型鏈上。
D.prototype =new C(); //繼承
var o3=new D();
o3 instanceof D //true
o3 isntanceof C //true
談到instanceof 我們要多插入一個問題,就是function的arguments,我們大家也許認為arguments是一個Array,但如果用instanceof去測試回發現arguments不是一個Array對象,盡管看起來很像。
第三種:Object.prototype.toString
這是對象的一個原生擴展函數,用來精確區分數據類型
var type=Object.prototype.toString
console.log(type.call(‘‘)) //object String
console.log(type.call([])) //object Array
console.log(type.call({})) //object Object
console.log(type.call(false)) //object Boolean
console.log(type.call(null)) //object Null
console.log(type.call(undefined)) //object Undefined
console.log(type.call(function(){})) //object Function
一、toString方法和Object.prototype.toSting.call()的區別
var arr=[1,2];
直接對一個數組調用toString()方法,
console.log(arr.toString()); //輸出1,2 現在通過call方法指定arr數組為Object.prototype對象中的toString方法的上下文。 console.log(Object.prototype.toString.call(arr)); //輸出[Object Array] 錯誤理解:按照arr是Object對象的子集,應該toString()方法會繼承下來,所以兩個得到的結果應該是一樣的,但是現實是殘酷的。 原因:Object.prototype的toString方法確實被繼承下來了,但是很多東西總不會一層不變,作為兒子的數組重寫了toString方法,所以直接調用數組對象上面的toString方法調用到的實際是重寫後的方法,並不是Object.prototype中的toString方法。Array,Function等類型作為Object的實例,都重寫了toString方法,不同的對象類型調用toString()方法時,根據原型鏈的知識,調用的是重寫之後的toString方法(函數返回的是函數體內的字符串,Array返回的是元素組成的字符串) 應用場景:Object.prototype對象上的toString方法可以用來判斷數據類型 例如:Object.prototype.toString.call(arr); 輸出:[Object Array] 判斷是否是數組 例子2: var arr=[1,2,3]; console.log(Array.prototype hasOwnPrototype(‘toString‘)) //true console.log(arr.toString()) //1,2,3 delete Array.prototype.toString; //delete操作符可以刪除實例屬性 console.log(Array.prototype hasOwnPrototype(‘toString‘)) //false console.log(arr.toString()) //[object Array]; 刪除了Array的toString方法後,同樣采用arr.toString()方法調用,不再屏蔽Object原型方法的實例方法,arr最後調用了Object的toString方法。 而重寫後的toString方法可以把對象轉換成字符串,還可以把數值轉換成不同進制的數字 [1,2].toString();//1,2 得到字符串 (10).toString(2) //十進制轉二進制,輸出1010,如果10.toString(2)會報錯,因為js會認為.是數字的小數點而不是調用符號。 二、為什麽用Object.prototype.toString.call(obj)檢測對象類型?
從toString()方法到Object.prototype.toString.call()方法