JavaScript學習(3)——方法
阿新 • • 發佈:2018-12-31
在一個物件中繫結函式,稱為該物件的方法。
在JS中,物件的定義是這樣的:
var xiaoming = {
name: '小明',
birth: 1990
};
但是,如果我們給xiaoming
繫結一個函式,就可以做更多的事情。比如, 寫個age()
方法,返回xiaoming
的年齡:
var xiaoming = { name: '小明', birth: 1990, age: function () { var y = new Date().getFullYear(); return y - this.birth; } }; xiaoming.age; xiaoming.age();
this指向當前物件。但是this在JS設計中是一個很坑的東西。要保證this的指向正確,必須用obj.xxx()
的形式呼叫!
由於這是一個巨大的設計錯誤,要想糾正可沒那麼簡單。ECMA決定,在strict模式下讓函式的this
指向undefined
,因此,在strict模式下,你會得到一個錯誤:
'use strict'; var xiaoming = { name: '小明', birth: 1990, age: function () { var y = new Date().getFullYear(); return y - this.birth; } }; var fn = xiaoming.age; fn(); // Uncaught TypeError: Cannot read property 'birth' of undefined
而且如果在方法的函式內部再指定函式,this又會指向undefined了(strict模式下)。this只在方法的函式中指向物件本身。
所以一個比較好的辦法時,在方法的函式中先用一個變數that捕獲this,然後在定義的函式中用that來代替this。
'use strict'; var xiaoming = { name : '小明', birth: 1990, age: function () { var that = this;//在方法內部一開始就捕獲this function getAgeFromBirth() { var y = new Date().getFullYear(); return y - that.birth; } return getAgeFromBirth(); } }; xiaoming.age(); //25
apply
雖然在一個獨立的函式呼叫中,根據是否是strict模式,this指向不同的物件,但是其實this指向的物件也是可以控制的。
要指定this指向的物件,可以用函式本身的apply方法,它接收兩個引數,一個引數是需要繫結的this
變數,另一個是Array
,表示函式本身的引數。
用apply
修復getAge()
呼叫:
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name : '小明',
birth: 1990,
age: getAge
};
xiaoming.age();
getAge.apply(xiaoming, []);
另一個類似的方法是call()
,唯一區別是:
- apply()把引數打包成
array
再傳入; - call()把引數按照順序傳入。
比如呼叫Math.max(3, 5, 4)
,分別用apply()
和call()
實現如下:
Math.max.apply(null,[3,5,4]); // 5
Math.max.call(null,3,5,4);// 5
對普通函式呼叫,我們通常把this
繫結為null
。
利用apply()
我們還可以動態改變函式的行為。
JS的所有物件是動態的,即使內建的函式,我們也可以重新指向新的函式。
例如想要統計一個程式中呼叫了多少次parseInt(),,可以通過替換函式來完成:
'use strict';
car count = 0;
var oldParseInt = parseInt; // 儲存原函式
window.parseInt = function() {
count += 1;
return oldParseInt.apply(null, arguments);// 呼叫原函式
};
parseInt('10');
parseInt('20');
parseInt('30');
console.log('count = ' + count); // 3