0%

JS 函式的方法與 This

函式也是一個物件,所以也會有它的方法,需要以物件的方式調用,

1
2
3
4
5
6
7
function fun() {
console.log('我是fun函式');
console.log(this);
}

fun.call(); // 我是fun函式
fun.apply(); // 我是fun函式

剛開始接觸程式時,常常把funfun()搞混,其實這兩者是不同的,fun指的是這個函式本身,函式在 Javascript 裡是物件型別,所以fun也是一個物件。fun()指的是呼叫這個函式。

使用函式的方法call()apply()都必須以物件的方式調用,且會執行此函式。當我們使用fun(),fun.call()fun.apply()時,都會執行fun()此函式,但有什麼不同?
使用函式的call()apply()方法可修改 this,因為可以將一個物件,指定為這兩個方法的第一個參數,如果沒使用這兩個方法,單純執行函式,函式的 this 是 window。

1
2
3
4
5
6
7
8
9
function fun() {
console.log(this);
}

let obj = {};

fun(); // Window
fun.call(obj); // {}
fun.apply(obj); // {}
1
2
3
4
5
6
7
8
9
10
11
12
function fun(a, b) {
console.log('a = ' + a);
console.log('b = ' + b);
//alert(this);
}

var obj = {
name: 'obj',
sayName: function () {
alert(this.name);
},
};

call()和 apply()

  • 這兩個方法都是函式物件的方法,需要通過函式物件來調用
  • 當對函式調用 call()和 apply()都會調用函式執行
  • 在調用 call()和 apply()可以將一個物件指定為第一個參數
    此時這個物件將會成為函式執行時的 this
  • call()方法可以將實參在物件之後依次傳遞
  • apply()方法需要將實參封裝到一個陣列中統一傳遞

this 的情況:

  • 以函式形式呼叫時,this 永遠都是 window
  • 以方法的形式調用時,this 是調用方法的物件
  • 以構造函式的形式調用時,this 是新創建的那個物件
  • 使用 call 和 apply 調用時,this 是指定的那個物件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//fun.call(obj,2,3);
fun.apply(obj, [2, 3]);

var obj2 = {
name: 'obj2',
};

/*fun.apply();
fun.call();
fun();*/

//fun.call(obj);
//fun.apply(obj);

//fun();

//obj.sayName.apply(obj2);

這題的重點是 add()出現兩次!雖然程式是一行行跑的,但是因為 JS 的 hoisting 特色,所以所有的函式都會優先被提升,而在提升的規則裡,如果有重複的變數或函式,後面的會覆蓋前面的,所以第一個add()基本上是無效的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var x = 1,
var y = (z = 0);

function add(n) {
return (n = n + 1);
}

y = add(x); // 2

function add(n) {
return (n = n + 3);
}

z = add(x); // 4

arguments所依據的是實參而不是形參。

1
2
3
4
5
6
7
// A
function foo(x) {
console.log(arguments);
return x;
}

foo(1, 2, 3, 4, 5);
1
2
3
4
5
6
7
8
// B
(function foo(x) {
console.log(arguments);
return x;
})(1, 2, 3, 4, 5;)


foo(1, 2, 3, 4, 5);