0. 開場白
我個人博客現在還沒正式
上線,不過從簡書的點擊率來看,之前的文章每篇大概有100來個人會點擊進來,其實這種點擊我已經是比較心滿意足了(如果你經歷過每篇文章只有不到10個人點擊的日子,或許也會理解我現在的心理狀態)。
今天繼續寫每天學點javascript
。其實這個系列文章用這樣的標題主要是為了吸引眼球,并不是說我一定每天都會發一篇這類文章。畢竟有時候事情多,如果太過強迫自己每天來連載的話在某種程度上肯定會降低了文章的質量,這是不可取的,我只能保證會堅持連載,并且盡可能多寫,但不能保證每天
。當文章累積到足夠的數量的時候,或許就能夠讓讀者有一種每天學點
的感覺吧。
今天還是講述兩個方法:
Object.getPrototypeOf
獲取傳入參數的原型
Object.toString
, Object.prototype.toString
定義對象的字符串表示
內容比較簡單,大牛們可以選擇跳過,或者留言吐槽。
1. 正文
Object.getPrototypeOf
獲取傳入參數的原型
通過這個方法,以對象作為參數傳入,則可以返回這個對象的原型,使用方式比較簡單,犀牛書第三部分也有提供例子,我對例子稍做修改
> var strObject = new String("lanzhiheng") // 創建字符串對象,原型是String.prototype
undefined
> Object.getPrototypeOf(strObject) // 獲取新創建對象的原型
[String: '']
我擦,這肯定看不出什么是吧,就算我這樣做
> String.prototype
[String: '']
似乎也只能說明,String.prototype
碰巧換算出來是[String: '']
,誰能保證它就是創建strObject
的原型?
我們還記得用
==
比較兩個指向對象的變量,只有當它們都指向同一個對象的時候才相等嗎?
> {} == {} // 兩個不同的對象
false
> var a = b = {}
undefined
> a == b // a和b指向同一個對象
true
用同樣的原理我們可以這樣判斷
> Object.getPrototypeOf(strObject) == String.prototype
true
哈哈,這樣就可以判斷出,strObject
的原型其實就是String.prototype
。更進一步
> var obj = {};
undefined
> var nextObj = Object.create(obj) // 以obj為原型創建一個新的對象
undefined
> Object.getPrototypeOf(nextObj) == obj // 它的原型就是obj
true
這樣應該了解這個方法的作用了吧?
Object.toString
, Object.prototype.toString
定義對象的字符串表示
幾乎是每一個類型都有它自己的toString
類方法,當然null
這種肯定就沒有了。另外,幾乎所有對象也有它們對應類型的toString
方法,這個是從原型鏈繼承來的,也就是Object.prototype.toString
。這個原型的Object.prototype.toString
方法跟Object.toString
是不一樣的。前者是可以通過原型鏈條傳承下去,而后者只是Object
這個類型的一個類方法而已。
> Object.toString == Object.prototype.toString // 它們是不一樣的
false
> var b = Object.create(Object.prototype)
undefined
> b.toString == Object.prototype.toString // 通過原型鏈繼承下去了
true
可見,對象的屬性沒有進行任何重載的情況下調用的依然是原型鏈中的Object.prototype.toString
方法。
當然,我們很少會主動去調用,一般它們會在需要的時候自動調用, 你看:
> Object.prototype.toString()
'[object Object]'
> var a = 1
undefined
> a + Object.prototype
'1[object Object]'
后面的Object.prototype
自動調用了toString
,然后才進行了字符串的拼接操作(當然變量a也進行了類似的轉換)。
除此之外,Object.prototype.toString作為最為原始的
toString`版本可以用來判斷對象屬于什么類型。
> function classOf(p) { // 定義這個樣一個方法
... if (p === null) return 'null';
... if (p === undefined) return undefined;
... return Object.prototype.toString.call(p).slice(8, -1);
... }
undefined
> classOf(1)
'Number'
> classOf(null)
'null'
為什么要調用原始版本?每個不同的類型的原型上不是都有toString嗎?
正是因為每種不同類型的原型都可能有它們自己定制的toString
。我們需要的才必須是Object.prototype.toString
這個方法,如:
> (new Date()).toString()
'Wed Oct 26 2016 09:00:31 GMT+0800 (CST)'
> (new Number()).toString()
'0'
> (new Object()).toString()
'[object Object]'
只有Object.prototype.toString
會返回類似[object Number]
的結果,我們只需要拿最后的Number
便可。
但是這個東西并不能是總能判斷出一個對象的所屬類,如果它不是內置類型的話,我們就不能這樣干了。
> function Range(x) {this.x = x} // 創建一個類
undefined
> var r = new Range() // 創建這個類的對象
> classOf(new Range())
'Object'
可見,得出的類型只是Object
。我們沒辦法通過這種方式得出結果Range
。這個在使用的時候還是要多加注意。
2. 最后
這兩個方法還是比較容易理解的,原諒我不小心就說了那么多。很感謝你能看到最后。