JS基礎系列(三): JS里的對象

全局對象window


在說全局對象之前, 我們先講一個小知識點

JS規(guī)定, 如果首行是大括號, 一律解釋為代碼塊

{foo: 123}

如果要解釋為表達式(對象), 則必須在大括號前加圓括號

({foo: 123})

global(瀏覽器里就是window)

window的屬性大致分為兩類, 一類是ECMAScript規(guī)程, 一類是瀏覽器環(huán)境私有的, 如

ECMAScript規(guī)定 私有(chrome/firefox等)
parseInt alert
parseFloat prompt
Nmuber comfirm
String console
Boolean document
setTimeout history

window有哪些屬性和方法可以查看mdn

這里給大家說一點需要注意的地方, 我們用字面量的方式聲明數(shù)字和用new Number()聲明的數(shù)字是不一樣的, 用new Number()聲明的數(shù)字是一個對象

let n1 = 1
let n2 = new Number(1)

n1是一個簡單類型, n2實際上是一個對象

當我們用n1.toString()時, js會先把n1臨時轉換成Number對象, 然后使用對象的toString()方法, 轉換之后臨時對象Number即銷毀
下面的代碼就很明白說明這個過程了

let n = 1
n.name = 'Adam'
n.name //undefined

上面的代碼, 我們給n一個name屬性, 這是js解釋器會把n轉換成一個Number對象, 然后給這個對象賦值'Adam', 然后這個對象就銷毀了

當我們調用n.name時,js解釋器會再創(chuàng)造一個新的Number對象, 這個對象并沒有name屬性, 所以是undefined

這個對也String()等也同樣適用

幾個有用的string類型API

trim()去掉字符串前后的空格

'   username   '.trim()
'uername'

concat()連接兩個字符串,返回一個新字符串

let s1 = 'Hello'
let s2 = 'World'
s1.concat(s2)
'HelloWorld'

slice(index, length)截取字符串, 返回一個新字符串

let s1 = 'Hello'
s1.slice(0,2)
'He'

replace(oldLetter, newLetter)替換第一個匹配字符串, 并替換成新字符, 返回一個新字符串

let s1 = 'Hello'
s1.replace('l', 'o')
'Heolo'


構造函數(shù)


JS使用構造函數(shù)作為對象的模版, 構造函數(shù)在不用new時, 就是普通函數(shù)

let b = new Vehicle()let b = new Vehicle 等價

不使用new時, 構造函數(shù)變成就變成普通函數(shù), this這時代表全局對象

let Vehicle = function () {
  this.price = 1000
}

let v = Vehicle()
v //undefined
price //1000

new 做了什么

  1. 創(chuàng)建一個空對象, 作為將要返回的對象實例
  2. 將這個空對象的proto, 指向構造函數(shù)的prototype屬性
  3. 將空對象賦值給函數(shù)內部this關鍵字
  4. 開始執(zhí)行構造函數(shù)內部的代碼
  5. 返回構造函數(shù)
  6. 如果構造函數(shù)內部有return語句, 而且return一個對象, new命令會直接返回該對象

this 關鍵字

全局環(huán)境

function fn() {
  console.log(this === window)
}
 fn() //true

構造函數(shù)

這個就是上面提到的new

對象的方法

let obj = {
  foo: function() {
    console.log(this)
  }
}
obj.foo() //obj

下面情況, 會改變this指向
(obj.foo = obj.foo)() //window
(false || obj.foo)() //window
(1, obj.foo)() //window

第一個等價于

(obj.foo = function(){console.log(this)})()
(function() {console.log(this)})()

第二個等價于
(false || function() {console.log(this)})()

第三個等價于
(1, funciton() {console.log(this)})()

如果this所在的方法不在第一層, this就只是指向當前一層對象, 不會繼承更上層

let a = {
  p: 'Hello', 
  b: {
    m: function() {
      console.log(this.p)
    }
  }
}
a.b.m() //undefined

所以請使用call apply bind方法強制綁定this, 就不會亂了

關于this的用法還有另一篇文章中也提到了, 有興趣的可以看一看


原型


我們聲明一個函數(shù)

function fn(){
}

對于每一個聲明的函數(shù), 都會有一個prototype屬性, 有且只有函數(shù)才有prototype屬性

所以fn也會有一個fn.prototype的屬性

當我們對函數(shù)使用new操作符時, 就會生成一個實例對象, fn就是這個實例對象的構造函數(shù)

實例對象就會自動生成一個__proto__的屬性,指向他的構造函數(shù)的prototype屬性, 所以當我們new fn()時, new出來的實例會自動有一個__proto__屬性指向fn.prototype

這個prototype屬性, 我們就給它取個名字, 叫原型

我們給fn函數(shù)new一個實例對象

function fn() {}

let obj = new fn()

obj.__proto__ === fn.prototype // true

上面的話總結起來, 就是下面這個圖

原型

我們繼續(xù)延續(xù)上面的說下去,其實prototype屬性, 仍然有__proto__屬性滨嘱, 所有函數(shù)的prototype屬性最終都會指向Object.prototype

fn.prototype.__proto__ = Object,prototype

因為Object.prototype中包含toString等方法, 這就是為什么所有對象都能調用toString等方法的原因

我們可以發(fā)散一下

let string = new String('aaa')
string.__proto__ === String.prototype //true
string.__proto__.__proto__ === Object.prototype //true

我們繼續(xù)發(fā)散一下, 我們創(chuàng)建一個函數(shù), 會不會有__proto__

function fn() {}

fn.__proto__ === Function.prototype //true

對于聲明函數(shù)來說,fn有一個prototype, 并且fn.prototype.__proto__ === Object.prototype

fn還有一個__proto__, 并且fn.__proto__ === Function.prototype

是不是有點燒腦呢瓤介?

再來個燒腦的, Object, Number, String, Boolean, Function這些構造函數(shù)的proto指向

Object.__proto__ === Function.prototype //true
Number.__proto__ === Function.prototype //true
String.__proto__ === Function.prototype //true
Boolean.__proto__ === Function.prototype //true
Function.__proto__ === Function.prototype //true

我們發(fā)現(xiàn),所有構造函數(shù)的proto都指向Function.prototype, 因為所有函數(shù)都是通過new Function()創(chuàng)造出來的

總結下來, 就是下面的圖

終極原型

以及


Function原型
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末凿菩,一起剝皮案震驚了整個濱河市牌柄,隨后出現(xiàn)的幾起案子魄鸦,更是在濱河造成了極大的恐慌趴生,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件氢架,死亡現(xiàn)場離奇詭異,居然都是意外死亡朋魔,警方通過查閱死者的電腦和手機岖研,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來警检,“玉大人孙援,你說我怎么就攤上這事∩鹊瘢” “怎么了拓售?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長洼裤。 經(jīng)常有香客問我邻辉,道長,這世上最難降的妖魔是什么腮鞍? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任值骇,我火速辦了婚禮,結果婚禮上移国,老公的妹妹穿的比我還像新娘吱瘩。我一直安慰自己,他們只是感情好迹缀,可當我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布使碾。 她就那樣靜靜地躺著,像睡著了一般祝懂。 火紅的嫁衣襯著肌膚如雪票摇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天砚蓬,我揣著相機與錄音矢门,去河邊找鬼。 笑死灰蛙,一個胖子當著我的面吹牛祟剔,可吹牛的內容都是我干的。 我是一名探鬼主播摩梧,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼物延,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了仅父?” 一聲冷哼從身側響起叛薯,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤浑吟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后案训,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體买置,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年强霎,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蓉冈。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡城舞,死狀恐怖,靈堂內的尸體忽然破棺而出寞酿,到底是詐尸還是另有隱情家夺,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布伐弹,位于F島的核電站拉馋,受9級特大地震影響,放射性物質發(fā)生泄漏惨好。R本人自食惡果不足惜煌茴,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望日川。 院中可真熱鬧蔓腐,春花似錦、人聲如沸龄句。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽分歇。三九已至傀蓉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間职抡,已是汗流浹背葬燎。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留繁调,地道東北人萨蚕。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像蹄胰,于是被迫代替她去往敵國和親岳遥。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內容