溫故而知新篇之《JavaScript忍者祕籍(第二版)》學習總結(二)——函數進階篇

前言

這本書的電子版我已經在學習總結第一篇已經放了下載連接了,能夠去查看
溫故而,知新篇之《JavaScript忍者祕籍(第二版)學習總結(一)——函數篇面試

最近看了一句話,以爲挺不錯的,分享下:編程

「不要把本身的努力看的過重,你本身以爲作這個很努力,作那個很努力;當你奔跑、跌倒的同時,有人比你已經先站起來跑了。
其實,努力應該是生活的常態,不該該被認爲是稀缺、難得的品質
而不是說 你努力了,你就應該和別人在不少事情上不同。你應該不斷的提高本身才是努力的意義。segmentfault

我簡直了,文鄒鄒的~~~哈哈哈哈。
來來來,說正題數組


arguments參數

arguments對象有一個名爲length的屬性,表示實參的確切個數。經過數組索引的方式能夠獲取單個參數的值,例如,arguments[2]將獲取第三個參數app

function(a,b,c){
//arguments[0]=a
//arguments[1]=b
console.log(arguments[2] === c) // true
}

你可能會被它的用法誤導,畢竟它有length屬性,並且能夠經過數組下標的方式訪問到每個元素。但它並不是JavaScript數組,若是你嘗試在arguments對象上使用數組的方法(例如,上一章中用到的sort方法),會發現最終會報錯。arguments對象僅是一個類數組的結構,在使用中要尤其注意。函數

arguments對象做爲函數參數的別名

function infiltrate(person) {
 arguments[0] = 'ninja';
 person === 'ninja' // true
 
 //同理
 person = 'gardener';
 arguments[0] === 'gardener' // true
}

注意⚠️:

嚴格模式避免使用arguments別名學習

"use strict";  ⇽--- 開啓嚴格模式
function infiltrate(person) {
    arguments[0] = 'ninja';  ⇽--- 改變第一個參數」
    arguments[0] === 'ninja' // true
    person === 'gardener' // false

}

this參數:函數上下文

函數調用

咱們能夠經過4種方式調用一個函數,每種方式之間有一些細微差異。
  • 做爲一個函數(function)——skulk(),直接被調用。
  • 做爲一個方法(method)——ninja.skulk(),關聯在一個對象上,實現面向對象編程。
  • 做爲一個構造函數(constructor)——new Ninja(),實例化一個新的對象。
  • 經過函數的apply或者call方法——skulk.apply(ninja)或者skulk.call(ninja)。

這裏要補充下,書中有說,做爲函數直接被調用、做爲方法被調用
這段內容,我當時在理解的時候,覺得本身理解了。後來作了幾道題才明白這個意思。this

var a=10
function b(){
  console.log(a) // 10 // 當前語義環境
  console.log(this.a) // 20  執時環境
}

var c={
  a:20,
  ninja:b
}
console.log(c.ninja())

注意⚠️:

上面的例子中,b不是c的一個方法,b是一個獨立的函數。
當經過方法飲用去調用函數時,c.ninja(),對函數調用時,上下文就是c;spa

this,
當直接經過函數名調用,也就是將函數做爲函數調用時,由於是在非嚴格模式下執行,所以預期的函數上下文結果應當是全局上下文(window)code

做爲構造函數調用

function Ninja() {
 this.skulk = function() {
   return this;
 };
}  ⇽--- 構造函數建立一個對象,並在該對象也就是函數上下文上添加一個屬性skulk。這個skulk方法再次返回函數上下文,從而能讓咱們在函數外部檢測函數上下文

var ninja1 = new Ninja();
var ninja2 = new Ninja();  ⇽--- 經過關鍵字new調用構造函數建立兩個新對象,變量ninja1和變量ninja2分別引用了這兩個新對象

console.log(ninja1.skulk() === ninja1,
 "The 1st ninja is skulking");
console.log(ninja2.skulk() === ninja2,
 "The 2nd ninja is skulking");  ⇽--- 檢測已建立對象中的skulk方法。每一個方法都應該返回自身已建立的對象

當使用關鍵字new調用函數時,會建立一個空的對象實例並將其設置爲構造函數的上下文(this參數)

注意⚠️:

面試的時候老是會問到。
通常來說,當調用構造函數時會發生一系列特殊的操做
使用關鍵字new調用函數會觸發如下幾個動做。

1.建立一個新的空對象。
2.該對象做爲this參數傳遞給構造函數,從而成爲構造函數的函數上下文。
3.新構造的對象做爲new運算符的返回值(除了咱們很快要提到的狀況以外)。
image

構造函數的返回值

  • 若是構造函數返回一個對象,則該對象將做爲整個表達式的值返回,而傳入構造函數的this將被丟棄。
  • 可是,若是構造函數返回的是非對象類型,則忽略返回值,返回新建立的對象。

箭頭函數 this

var Button={
  clicked:false,
  click:()=>{
    this.clicked = true;
    console.log(this) // window
  }
}
Button.click()
function Button(){
  clicked=false
  click=()=>{
    this.clicked = true;
    console.log(this) // window
  }
}
Button()
click()

注意⚠️:

因爲this值是在箭頭函數建立時肯定的
`在全局代碼中定義對象字面量,在字面量中定義箭頭函數,那麼箭頭函數內的this指向全局window對象`

小結:

  • 當調用函數時,除了傳入在函數定義中顯式聲明的參數以外,同時還傳入兩個隱式參數:arguments與this
arguments參數是傳入函數的全部參數的集合。具備length屬性,表示傳入參數的個數,經過arguments參數還可獲取那些與函數形參不匹配的參數。在非嚴格模式下,arguments對象是函數參數的別名,修改arguments對象會修改函數實參,能夠經過嚴格模式避免修改函數實參。
this表示函數上下文,即與函數調用相關聯的對象。函數的定義方式和調用方式決定了this的取值。
  • 函數的調用方式有4種。
做爲函數調用:skulk()。
做爲方法調用:ninja.skulk()。
做爲構造函數調用:new Ninja()。
經過apply與call方法調用:skulk.apply(ninja)或skulk.call(ninja)。
  • 函數的調用方式影響this的取值。
若是做爲函數調用,在非嚴格模式下,this指向全局window對象;在嚴格模式下,this指向undefined。
做爲方法調用,this一般指向調用的對象。
做爲構造函數調用,this指向新建立的對象。
經過call或apply調用,this指向call或apply的第一個參數。
  • 箭頭函數沒有單獨的this值,this在箭頭函數建立時肯定。
  • 全部函數都可使用bind方法,建立新函數,並綁定到bind方法傳入的參數上。被綁定的函數與原始函數具備一致的行爲。

摘錄來自: [美] John Resig Bear Bibeault Josip Maras. 「JavaScript忍者祕籍(第2版)。」 iBooks.

相關文章
相關標籤/搜索