方法與函數(shù)
在一個對象中綁定函數(shù),稱為這個對象的方法。
this的各種坑!??!
1. 先來個正常的,this指向執(zhí)行環(huán)境的對象
var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
var y = new Date().getFullYear();
return y - this.birth;
}
};
xiaoming.age; // function xiaoming.age()
xiaoming.age(); // 今年調(diào)用是25,明年調(diào)用就變成26了
2. “this指向執(zhí)行環(huán)境的對象”
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name: '小明',
birth: 1990,
age: getAge
};
xiaoming.age(); // 25, 正常結(jié)果
getAge(); // NaN
function getAge是綁定在window下的函數(shù),就相當(dāng)于window的方法,this指向window理所當(dāng)然。
getAge此時(shí)是回調(diào)函數(shù)。等同于如下寫法:(與1中一樣)
var xiaoming = {
name: '小明',
birth: 1990,
age: function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
};
與此類似:
var fn = xiaoming.age; // 先拿到xiaoming的age函數(shù)
fn(); // NaN
在非嚴(yán)格模式下,變量未被定義就被調(diào)用,返回NaN。(沒毛病)
'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
在嚴(yán)格模式下,變量未被定義就被調(diào)用,返回undefined(指向Undefined對象)。(沒毛病)
總之:正確的姿勢是object.xxx()的調(diào)用指向正確
xiaoming.age()//this指向xiaoming
3. 修復(fù)方法。用一個that變量首先捕獲this:
'use strict';
var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
var that = this; // 在方法內(nèi)部一開始就捕獲this
function getAgeFromBirth() {
var y = new Date().getFullYear();
return y - that.birth; // 用that而不是this
}
//定義其他方法,而不是把所有語句都堆到一個方法中
function getAgeFromBirth(){
var return that.birth;
}
return getAgeFromBirth();
}
};
用var that = this;,你就可以放心地在方法內(nèi)部定義其他函數(shù),而不是把所有語句都堆到一個方法中。
xiaoming.age(); // 25
4. 用arguments.callee()代替this也是不可以的。
arguments.callee()指向當(dāng)前調(diào)用的函數(shù),常用在匿名函數(shù)里指代該匿名函數(shù)。
apply()、call()、bind()理解
1. 要指定函數(shù)的this指向哪個對象,可以用函數(shù)本身的apply()方法
applyvt.“應(yīng)用”的意思。apply the Function to Object.(將函數(shù)應(yīng)用于某對象)
callvt.vi."需要"的意思。call for the Object.(需要某對象來運(yùn)行這個函數(shù))
簡單粗暴的這樣理解,便于記憶。
apply(thisObj,args)
thisObj表示函數(shù)內(nèi)this所指代的對象(Obj)(是誰),備選值:thisnullobject實(shí)例
thisObj為this時(shí),調(diào)用apply()的函數(shù)中this所指代的對象
thisObj為null時(shí),thisObj使用全局對象
thisObj為object實(shí)例時(shí),很常見
args表示傳入的參數(shù),可以是argument和Array實(shí)例
返回function執(zhí)行的值
例如:
//將默認(rèn)的Object.toString()應(yīng)用到對象o上,以覆蓋對象o中自定義的toString()方法。
Object.prototype.toString().apply(o);
//調(diào)用Math.max()方法來查找數(shù)組中的最大元素
var data = [1,2,3,4,5,6];
Max.max.apply(null,data);
window.color = "red";
var o = {
color:"blue";
}
function sayColor(){
alert(this.color);
}
sayColor(); //red
sayColor().apply(this);//red
sayColor().apply(window);//red
sayColor().apply(o);;//blue
call()與apply()類似
call(thisObj,arg1,arg2,......)
arg1,arg2,......表示按照順序傳入?yún)?shù)。
2. bind() ES5新增
bindvi. “捆綁”的意思。bind the Function to the Object.(將函數(shù)綁入對象里面,函數(shù)此時(shí)成了該對象的方法,也就是說,此時(shí)函數(shù)內(nèi)的this指向綁定的對象o)
bind(o,arg1,arg2,....)
例如:
function getName() {
console.log(this.name);
}
var o = {
name:xiaoxiao;
age:18;
};
var result=getName().bind(o);
result();//xiaoxiao
getName();//undefined or NaN
參數(shù)可以分兩次傳遞:
//假設(shè)f為一個函數(shù)
var g = f.bind(0,1,2);
//此時(shí)g為一個新函數(shù),g(3)等價(jià)于:
f.call(0,1,2,3);
var o1={
x:1,
getplus:function(y,z){
return this.x+y+z;
}
}
var o2={
x:11,
getplus:function(y,z){
return this.x*y;
}
}
//o1.getplus需要2個參數(shù),分兩次傳入
var result=o1.getplus.bind(o2,1);
//得到的result是函數(shù),函數(shù)result需要另一個參數(shù)才能計(jì)算x+y+z的值
result(3);//得出計(jì)算結(jié)果
var resultapply=o1.getplus.call(o2,1,2);//與上面兩步得出的結(jié)果一樣
使ES3也兼容bind()的方法:
//如果方法不存在,就在原型里添加
//提示:bind()返回的是函數(shù)
if(!Function.prototype.bind){
Function.prototype.bind=function(o /*,args*/){
var self=this,boundArgs=arguments;
//**此時(shí)Function是對象,this指向Funtion本身**,并把它保存起來
//arguments也保存起來,這里的arguments是第一次傳入的參數(shù),所以下面for循環(huán)從第二個參數(shù)開始
return function(){
var args=[],i;
for(i=1;i<boundArgs.length;i++) args.push(boundArgs[i]);
//遍歷第一次傳入的參數(shù),從第二位開始(第一位是對象)
for(i=0;i<arguments.length;i++) args.push(arguments[i]);
//遍歷第二次傳入的參數(shù),全部遍歷
return self.apply(o,args);
}
}
}

解釋:self的值是指向function的指針。
var result=o1.getplus.bind(o2,1);
其中o1.getplus方法(函數(shù))是圖中紅色的Function對象,而self指針是圖中的小this。