方法、this的讲解、apply&call&bind的理解

方法与函数

在一个对象中绑定函数,称为这个对象的方法。



this的各种坑!!!

1. 先来个正常的,this指向执行环境的对象

var xiaoming = {
    name: '小明',
    birth: 1990,
    age: function () {
        var y = new Date().getFullYear();
        return y - this.birth;
    }
};
xiaoming.age; // function xiaoming.age()
xiaoming.age(); // 今年调用是25,明年调用就变成26了

2. “this指向执行环境的对象

 function getAge() {
    var y = new Date().getFullYear();
    return y - this.birth;
}
var xiaoming = {
    name: '小明',
    birth: 1990,
    age: getAge
};
xiaoming.age(); // 25, 正常结果
getAge(); // NaN

function getAge是绑定在window下的函数,就相当于window的方法,this指向window理所当然。


getAge此时是回调函数。等同于如下写法:(与1中一样)

var xiaoming = {
    name: '小明',
    birth: 1990,
    age:  function getAge() {
    var y = new Date().getFullYear();
    return y - this.birth;
    
};

与此类似:

var fn = xiaoming.age; // 先拿到xiaoming的age函数
fn(); // NaN

非严格模式下,变量未被定义就被调用,返回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

严格模式下,变量未被定义就被调用,返回undefined(指向Undefined对象)。(没毛病)


总之:正确的姿势是object.xxx()的调用指向正确

xiaoming.age()//this指向xiaoming

3. 修复方法。用一个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; // 用that而不是this
        }
        //定义其他方法,而不是把所有语句都堆到一个方法中
        function getAgeFromBirth(){
            var return that.birth;
        }
        return getAgeFromBirth();
    }
};

var that = this;,你就可以放心地在方法内部定义其他函数,而不是把所有语句都堆到一个方法中。

xiaoming.age(); // 25

4. 用arguments.callee()代替this也是不可以的。

arguments.callee()指向当前调用的函数,常用在匿名函数里指代该匿名函数。



apply()call()bind()理解

1. 要指定函数的this指向哪个对象,可以用函数本身apply()方法

apply vt. “应用”的意思。apply the Function to Object.(将函数应用于某对象)
call vt.vi."需要"的意思。call for the Object.(需要某对象来运行这个函数)

简单粗暴的这样理解,便于记忆。

apply(thisObj,args)
thisObj表示函数内this所指代的对象(Obj)(是谁),备选值:this null object实例

  • thisObjthis时,调用apply()的函数中this所指代的对象
  • thisObjnull时,thisObj使用全局对象
  • thisObjobject实例时,很常见

args表示传入的参数,可以是argumentArray实例
返回function执行的值

例如:

//将默认的Object.toString()应用到对象o上,以覆盖对象o中自定义的toString()方法。
Object.prototype.toString().apply(o);
//调用Math.max()方法来查找数组中的最大元素
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,......表示按照顺序传入参数。

2. bind() ES5新增

bind vi. “捆绑”的意思。bind the Function to the Object.(将函数绑入对象里面,函数此时成了该对象的方法,也就是说,此时函数内的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

参数可以分两次传递:

//假设f为一个函数
var g = f.bind(0,1,2);
//此时g为一个新函数,g(3)等价于:
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个参数,分两次传入
  var result=o1.getplus.bind(o2,1);
  //得到的result是函数,函数result需要另一个参数才能计算x+y+z的值
  result(3);//得出计算结果
  var resultapply=o1.getplus.call(o2,1,2);//与上面两步得出的结果一样

使ES3也兼容bind()的方法:

//如果方法不存在,就在原型里添加
//提示:bind()返回的是函数
if(!Function.prototype.bind){
    Function.prototype.bind=function(o /*,args*/){
        var self=this,boundArgs=arguments;
            //**此时Function是对象,this指向Funtion本身**,并把它保存起来
            //arguments也保存起来,这里的arguments是第一次传入的参数,所以下面for循环从第二个参数开始
        return function(){
            var args=[],i;
            for(i=1;i
方法、this的讲解、apply&call&bind的理解_第1张图片
self为何指代被调用的方法

解释:self的值是指向function的指针。

var result=o1.getplus.bind(o2,1);

其中o1.getplus方法(函数)是图中红色的Function对象,而self指针是图中的小this

你可能感兴趣的:(方法、this的讲解、apply&call&bind的理解)