-
全局對象 window
ECMAScript 規(guī)定全局對象叫做 global,但是瀏覽器把 window 作為全局對象(瀏覽器先存在的)
window 就是一個(gè)哈希表,有很多屬性。
window 的屬性就是全局變量。
使用window的屬性可以不加window.
,
比如window.alert('警告')
可以寫成alert('警告')
這些全局變量分為兩種:一種是 ECMAScript 規(guī)定的
- global.parseInt
- global.parseFloat
- global.Number
- global.String
- global.Boolean
- global.Object
一種是瀏覽器自己加的屬性
- window.alert
- window.prompt
- window.comfirm
- window.console.log
- window.console.dir
- window.document
// document由瀏覽器實(shí)現(xiàn),但是也有一個(gè)自己的標(biāo)準(zhǔn),那就是 DOM,它的標(biāo)準(zhǔn)由 W3C 制定 - window.document.createElement
- window.document.getElementById
所有 API 都可以在 MDN 里找到詳細(xì)的資料。
-
全局函數(shù)&簡單類型與對象的區(qū)別
1. Number()
- MDN
- 阮一峰
Number('1') // 1 強(qiáng)制轉(zhuǎn)換
-
var n = new Number(1) // 返回一個(gè)值為1的對象
在這里,Number()對象作為構(gòu)造函數(shù)使用,用來生成值為數(shù)值的對象。 - 和直接賦值數(shù)字也就是簡單類型的區(qū)別:
- 一個(gè)是簡單類型,一個(gè)是復(fù)雜類型
- 兩者對內(nèi)存的使用不同,假設(shè)有
var n1 = 1
var n2 = new Number(1)
內(nèi)存圖: - 包裝對象有許多便捷的操作
- 你可以通過
valueOf()
來獲得n2
的原始值1
- 其它還有
toString() // 獲得字符串形式 toFixed() // 轉(zhuǎn)為指定位數(shù)的小數(shù),返回這個(gè)小數(shù)對應(yīng)的字符串 toExponential() // 將一個(gè)數(shù)轉(zhuǎn)為科學(xué)計(jì)數(shù)法形式 toPrecision() // 將一個(gè)數(shù)轉(zhuǎn)為指定位數(shù)的有效數(shù)字 (10).toString() // "10" // toString方法可以接受一個(gè)參數(shù),表示輸出的進(jìn)制。如果省略這個(gè)參數(shù),默認(rèn)將數(shù)值先轉(zhuǎn)為十進(jìn)制,再輸出字符串;否則,就根據(jù)參數(shù)指定的進(jìn)制,將一個(gè)數(shù)字轉(zhuǎn)化成某個(gè)進(jìn)制的字符串。 (10).toString(2) // "1010" (10).toString(8) // "12" (10).toString(16) // "a" // 上面代碼中,之所以要把10放在括號里,是為了表明10是一個(gè)單獨(dú)的數(shù)值,后面的點(diǎn)表示調(diào)用對象屬性。如果不加括號,這個(gè)點(diǎn)會被JavaScript引擎解釋成小數(shù)點(diǎn),從而報(bào)錯(cuò)。 // 只要能夠讓JavaScript引擎不混淆小數(shù)點(diǎn)和對象的點(diǎn)運(yùn)算符,各種寫法都能用。除了為10加上括號,還可以在10后面加兩個(gè)點(diǎn),JavaScript會把第一個(gè)點(diǎn)理解成小數(shù)點(diǎn)(即10.0),把第二個(gè)點(diǎn)理解成調(diào)用對象屬性,從而得到正確結(jié)果。 10..toString(2) // "1010" // 其他方法還包括 10 .toString(2) // "1010" 10.0.toString(2) // "1010" // toFixed方法用于將一個(gè)數(shù)轉(zhuǎn)為指定位數(shù)的小數(shù),返回這個(gè)小數(shù)對應(yīng)的字符串。 (10).toFixed(2) // "10.00" 10.005.toFixed(2) // "10.01" // toExponential方法的參數(shù)表示小數(shù)點(diǎn)后有效數(shù)字的位數(shù),范圍為0到20,超出這個(gè)范圍,會拋出一個(gè)RangeError。 (10).toExponential() // "1e+1" (10).toExponential(1) // "1.0e+1" (10).toExponential(2) // "1.00e+1" (1234).toExponential() // "1.234e+3" (1234).toExponential(1) // "1.2e+3" (1234).toExponential(2) // "1.23e+3" // toPrecision方法的參數(shù)為有效數(shù)字的位數(shù),范圍是1到21,超出這個(gè)范圍會拋出RangeError錯(cuò)誤。 (12.34).toPrecision(1) // "1e+1" (12.34).toPrecision(2) // "12" (12.34).toPrecision(3) // "12.3" (12.34).toPrecision(4) // "12.34" (12.34).toPrecision(5) // "12.340"
- 兩種賦值方式的歷史:
var n = new Number(1)
是當(dāng)初被要求要像java才做出來的方式,實(shí)際上更受人喜歡的依然是var n = 1
,
但是這樣方式無法使用Number對象的方法怎么辦,于是又有了下面的東西; - 基本包裝類型
理論上基本類型是不能沒有toString()
之類的方法的,然而實(shí)際上卻可以使用,
這是因?yàn)槊慨?dāng)?shù)貐^(qū)一個(gè)基本類型值的時(shí)候,后臺就會創(chuàng)建一個(gè)對應(yīng)的基本包裝類型的對象,從而讓我們能夠調(diào)用一些方法來操作這些數(shù)據(jù),如下:
也因此,var n = 1 // 1 var s = n.toString() // '1' // 后臺自動操作 var temp = new Number(n) // 創(chuàng)建一個(gè) Number 類型的實(shí)例 temp.toString() // 調(diào)用指定方法 // 然后將temp.toString()的值作為n.toString()的值 // 最后銷毀temp,釋放空間 // 所以這是一種臨時(shí)的轉(zhuǎn)換,基本類型實(shí)際上并沒有屬性,
var n = new Number(1)
這種方式基本不再被大家所使用 - 思考題
var n = 1 n.xxx = 2 // 問:是否會報(bào)錯(cuò)? // NO! n.xxx = 2 // 2 n.xxx // undefined
解析:n.xxx = 2這段代碼執(zhí)行時(shí)新建了一個(gè)臨時(shí)變量temp以及屬性xxx儲存值2,所以不會報(bào)錯(cuò),
但是執(zhí)行 n.xxx 的時(shí)候?yàn)g覽器顯示的卻是 undefined,這是因?yàn)?temp 是臨時(shí)創(chuàng)建出來了,使用后會立即銷毀,執(zhí)行 n.xxx 的時(shí)候上一句代碼創(chuàng)建的臨時(shí)temp已經(jīng)被銷毀了,這時(shí)候又是一個(gè)新的temp,它并沒有xxx這個(gè)屬性以及值
- String()和Boolean()也是同理
- 阮一峰
- JavaScript高級程序設(shè)計(jì)第五章-5.6-基本包裝類型
2. String()
- MDN
- MDN學(xué)習(xí)教程
- 阮一峰
var s = 'abc' var s2 = new String(s) // charAt方法返回指定位置的字符,參數(shù)是從0開始編號的位置。 s.charAt(1) // "b" s.charAt(s.length - 1) // "c" // 這個(gè)方法完全可以用數(shù)組下標(biāo)替代。 'abc'.charAt(1) // "b" 'abc'[1] // "b" // 如果參數(shù)為負(fù)數(shù),或大于等于字符串的長度,charAt返回空字符串。 'abc'.charAt(-1) // "" 'abc'.charAt(3) // "" // charCodeAt方法返回給定位置字符的Unicode碼點(diǎn)(十進(jìn)制表示),相當(dāng)于String.fromCharCode()的逆操作。 'abc'.charCodeAt(1) // 98 // 如果沒有任何參數(shù),charCodeAt返回首字符的Unicode碼點(diǎn)。 'abc'.charCodeAt() // 97 // 如何返回 16 進(jìn)制表示的Unicode碼點(diǎn) 'abc'.charCodeAt(0).toString(16) // trim方法用于去除字符串兩端的空格,返回一個(gè)新字符串,不改變原字符串。 ' hello world '.trim() // "hello world" // 該方法去除的不僅是空格,還包括制表符(\t、\v)、換行符(\n)和回車符(\r)。 '\r\nabc \t'.trim() // 'abc' // concat方法用于連接兩個(gè)字符串,返回一個(gè)新字符串,不改變原字符串。 var s1 = 'abc'; var s2 = 'def'; s1.concat(s2) // "abcdef" s1 // "abc" s2 // "def" // 該方法可以接受多個(gè)參數(shù)。 'a'.concat('b', 'c') // "abc" // slice方法用于從原字符串取出子字符串并返回,不改變原字符串。 // 它的第一個(gè)參數(shù)是子字符串的開始位置,第二個(gè)參數(shù)是子字符串的結(jié)束位置(不含該位置)。 'JavaScript'.slice(0, 4) // "Java" // 如果省略第二個(gè)參數(shù),則表示子字符串一直到原字符串結(jié)束。 'JavaScript'.slice(4) // "Script" // 如果參數(shù)是負(fù)值,表示從結(jié)尾開始倒數(shù)計(jì)算的位置,即該負(fù)值加上字符串長度。 'JavaScript'.slice(-6) // "Script" 'JavaScript'.slice(0, -6) // "Java" 'JavaScript'.slice(-2, -1) // "p" // 如果第一個(gè)參數(shù)大于第二個(gè)參數(shù),slice方法返回一個(gè)空字符串。 'JavaScript'.slice(2, 1) // ""
- String()有很多api,這里只寫了幾個(gè)常用的,更多詳見上面兩個(gè)鏈接
3. Boolean()
- MDN
- 阮一峰
var b = new Boolean(true) b.toString() // 'true' b.valueOf() // true // 踩坑 var f = false var f2 = new Boolean(false) if(f) { console.log(1) } if(f2) { console.log(2) } // 問:會打印出什么? 2 // 只打印 2,因?yàn)?f2 并不是 false,因?yàn)樗且粋€(gè)對象,而對象是 true // 別忘記js中只有 NAN、null、undefined、''、0是false,而對象和其它的都是true
4. Object()
-
公共屬性(原型)
var n = new Numer(1) var s = new String('a') var b = new Boolean(true) var o = new Object() // 上面4個(gè)不同的對象都有`toString()、valueOf()`屬性,可是如果每個(gè)對象都創(chuàng)建2個(gè)屬性會很浪費(fèi)內(nèi)存, // 所以,共用就好了
那么怎么訪問公共屬性呢?每個(gè)對象的toString儲存公共屬性的toString的地址?不
-
proto
js通過隱藏屬性__proto__
屬性來訪問公共屬性,它指向了那些所有對象共有的屬性
步驟:- 首先查看自身是否是對象,如果不是就包裝對象
- 如果是對象就查看自身的 key 有沒有 toString,有的話就直接調(diào)用
- 如果沒有的話就通過
__proto__
查看你的共用屬性看有沒有,有的話就將你自身對應(yīng)的值打印出來
例子:
var o1 = {name: 'zero'} o1.toString() // [object Object] // 依照步驟來,o1是對象,o1沒有toString,查看共有屬性,有toString,打印o1對應(yīng)的值 // 不僅僅是o1,創(chuàng)建更多的對象也是一樣,所有的對象都有隱藏屬性`__proto__`,指向?qū)?yīng)的共有屬性 var o2 = {} o1 === o2 // false o1.toString() === o2.toString() // true
- 如果是Number對象呢?
var n = new Number(11) n.toString(16) // numer對象可以這樣,而oject對象是不能這樣toString(16)的
可以看見,Number重寫了toString屬性,以及添加一部分自己的屬性,
然后通過__proto__
指向Object,對象共有屬性
所以如同上圖,Number對象就是在第3步去Number重寫的屬性尋找,沒有的話去共有屬性找
Number對象的__proto__
指向Number重寫的共有屬性,Number重寫的共有屬性的__proto__
指向?qū)ο蠊灿袑傩?/li> -
除了Number以外,類似的還有String、Boolean(目前所學(xué)的)
- 原型鏈
對象的屬性和方法,有可能定義在自身,也有可能定義在它的原型對象。由于原型本身也是對象,又有自己的原型,所以形成了一條原型鏈(prototype chain),就像我們上面畫的圖一樣,
-
如果一層層地上溯,所有對象的原型最終都可以上溯到Object.prototype,即Object構(gòu)造函數(shù)的prototype屬性。Object.prototype 就是 Object對象的共有屬性,相對的,Number.prototype就是Number對象的共有屬性,而Number.prototype的proto又指向Object.prototype,也就是它的共有屬性,String和Boolean也是如此
看這張圖,結(jié)合前面所學(xué)的數(shù)據(jù)結(jié)構(gòu),是不是很有意思,
根節(jié)點(diǎn)是Object.prototype,三個(gè)子節(jié)點(diǎn)分別是String.prototype、Number.prototype、Boolean.prototype,
當(dāng)你執(zhí)行var str = new String('a')
時(shí),瀏覽器就會在堆中創(chuàng)建一個(gè)hash,str保存這個(gè)hash的地址,
這個(gè)hash也就是String對象中除了你定義的屬性外還有隱藏屬性proto指向String.prototype,String.prototype又指向Object.prototype,這就完成了String API的所有綁定,
Number和Boolean也是一樣 “原型鏈”的作用是,讀取對象的某個(gè)屬性時(shí),JavaScript 引擎先尋找對象本身的屬性,如果找不到,就到它的原型去找,如果還是找不到,就到原型的原型去找。如果直到最頂層的Object.prototype還是找不到,則返回undefined。
如果對象自身和它的原型,都定義了一個(gè)同名屬性,那么優(yōu)先讀取對象自身的屬性,這叫做“覆蓋”(overriding)。
需要注意的是,一級級向上,在原型鏈尋找某個(gè)屬性,對性能是有影響的。所尋找的屬性在越上層的原型對象,對性能的影響越大。如果尋找某個(gè)不存在的屬性,將會遍歷整個(gè)原型鏈。
-
prototype與proto
兩者都指向共用屬性
String.prototype 是 String 的共用屬性的引用(防止共用屬性被垃圾回收)
s.proto 是 String 的共用屬性的引用(這是你在用共用屬性)
proto 是對象的屬性,prototype 是函數(shù)的屬性
它們儲存的地址相同,指向的其實(shí)是同一個(gè)對象// 一些燒腦的東西 var obj1 = 函數(shù).prototype obj1.__proto__ === Object.prototype // 等于下面 函數(shù).prototype.__proto__ === Object.prototype var obj2 = 函數(shù) obj2.__proto__ === Function.prototype // 也就是 函數(shù).__proto__ === Function.prototype Function.__proto__ === Function.prototype Function.prototype.__proto__ === Obeject.prototype String.__proto__ === Function.prototype Number.__proto__ === Function.prototype Boolean.__proto__ === Function.prototype Object.__proto__ === Function.prototype
總之,記住公式:
對象.__proto__ === 函數(shù).prototype
函數(shù).__proto__ === Function.prototype
參考 那么,Object.prototype對象有沒有它的原型呢?回答是有的,就是沒有任何屬性和方法的null對象,而null對象沒有自己的原型。
Object.getPrototypeOf(Object.prototype) // null
上面代碼表示,Object.prototype對象的原型是null,由于null沒有任何屬性,所以原型鏈到此為止。
Object.prototype 就是 Object對象的共有屬性
-
proto
A22-JS里的對象
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
- 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
- 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
- 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
- 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
- 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
- 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
- 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
推薦閱讀更多精彩內(nèi)容
- js API1.全局對象NAN 非數(shù)字值的特殊值infinity 代表正無窮的數(shù)據(jù)undefined 2.函數(shù)屬性...
- 序 從最近的js入門系列的閱讀量逐步遞減,觀眾老爺?shù)呐d趣也不再能夠接受一些細(xì)節(jié)性的地方深度挖掘,讓我有了一些思考。...
- 一、JavaScript基礎(chǔ)知識回顧 1.1 JavaScript 1.1.1 javascript是什么? Ja...
- 函數(shù)和對象 1、函數(shù) 1.1 函數(shù)概述 函數(shù)對于任何一門語言來說都是核心的概念。通過函數(shù)可以封裝任意多條語句,而且...
- 為豐富大學(xué)生暑期三下鄉(xiāng)文化生活,展示學(xué)生踐行“中國夢”的青春風(fēng)采,簡書現(xiàn)舉辦“感悟三下鄉(xiāng) 青春筑夢行”暑期社會實(shí)踐...