第十章-函式(下)-js紅寶書筆記
阿新 • • 發佈:2021-02-01
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
閉包
單獨開一章節