1. 程式人生 > 其它 >第十章-函式(下)-js紅寶書筆記

第十章-函式(下)-js紅寶書筆記

技術標籤:JS學習筆記js

1. 函式內部

函式內部存在兩個特殊的物件:arguments 和 this。ES6新增了new.target 屬性。

1.1 arguments

一個類陣列物件,包含呼叫函式時傳入的所有引數。
之前已經多次提到,arguments物件還有一個 callee 屬性,是一個指向 arguments 物件所在函式的指標。

function factorial(num) { 
 if (num <= 1) { 
 return 1; 
 } else { 
 return num * arguments.callee(num - 1); 
 } 
}

上面程式碼中的arguments.callee可以代替函式名factorial實現遞迴。

1.2 this

1.2.1 在標準函式中,this 引用的是把函式當成方法呼叫的上下文物件,這時候通常稱其為 this 值。

window.color = 'red'; 
let o = { 
 color: 'blue' 
}; 
function sayColor() { 
 console.log(this.color); 
} 
sayColor(); // 'red' 
o.sayColor = sayColor; 
o.sayColor(); // 'blue'

1.2.2 在箭頭函式中,this引用的是定義箭頭函式的上下文

window.color = 'red'; 
let o =
{ color: 'blue' }; let sayColor = () => console.log(this.color); sayColor(); // 'red' o.sayColor = sayColor; o.sayColor(); // 'red'

將回調函式寫成箭頭函式可以避免一些問題。
避免this指向的不是想要的物件。

function King() { 
 this.royaltyName = 'Henry'; 
 // this 引用 King 的例項
 setTimeout(() => console.log(this.royaltyName), 1000
); } function Queen() { this.royaltyName = 'Elizabeth'; // this 引用 window 物件 setTimeout(function() { console.log(this.royaltyName); }, 1000); } new King(); // Henry new Queen(); // undefined

1.3 caller

這個屬性引用的是呼叫當前函式的函式
如果是在全域性作用域中呼叫的則為 null。

function outer() { 
 inner(); 
} 
function inner() { 
 console.log(inner.caller); 
} 
outer();

以上程式碼會顯示 outer()函式的原始碼。
降低耦合度可以用arguments.callee.caller

function outer() { 
 inner(); 
} 
function inner() { 
 console.log(arguments.callee.caller); 
} 
outer();

在嚴格模式下訪問 arguments.callee 會報錯

new.target

ES中的函式始終可以作為建構函式例項化一個新物件,也可以作為普通函式被呼叫。
new.target是為了區分到底使用哪種方式呼叫的

function King() { 
 if (!new.target) { 
 throw 'King must be instantiated using "new"' 
 } 
 console.log('King instantiated using "new"'); 
} 
new King(); // King instantiated using "new" 
King(); // Error: King must be instantiated using "new"

2.函式屬性與方法

兩個屬性:length和 prototype
兩個方法:apply()和 call()。

2.1 函式的length屬性

length 屬性儲存函式定義的命名引數的個數

function sayName(name) { 
 console.log(name); 
} 
function sum(num1, num2) { 
 return num1 + num2; 
} 
function sayHi() { 
 console.log("hi"); 
} 
console.log(sayName.length); // 1 
console.log(sum.length); // 2 
console.log(sayHi.length); // 0

2.2 函式的prototype屬性

prototype 是儲存引用型別所有例項方法的地方,這意味著 toString()、valueOf()等方法實際上都儲存在 prototype 上。
相關內容已經在第 8 章詳細介紹。

2.3 apply()方法和 call()方法

主要作用是傳入函式體內 this值的能力。
apply()方法接收兩個引數:

  • 函式內 this 的值。
  • 第二個引數可以是 Array 的例項,但也可以是 arguments 物件。
    call()方法和apply()方法差不多,只是把陣列的接收變成了一個個分散開的。
function sum(num1, num2) { 
 return num1 + num2; 
} 
function callSum(num1, num2) { 
 return sum.call(this, num1, num2); 
} 
console.log(callSum(10, 10)); // 20

下面這個例子可以看出這兩個方法的用法

window.color = 'red'; 
let o = { 
 color: 'blue' 
}; 
function sayColor() { 
 console.log(this.color); 
} 
sayColor(); // red 
sayColor.call(this); // red 
sayColor.call(window); // red 
sayColor.call(o); // blue

閉包

單獨開一章節