this指向 js

This指向问题

1.如果对象的方法里面包含thisthis的指向就是方法运行时所在的对象。该方法赋值给另一个对象,就会改变this的指向。

var o = {
  f1: function () {
    console.log(this);
    var f2 = function () {
      console.log(this);
    }();
  }
}

o.f1()
// Object
// Window

上边代码等价于

var temp = function () {
console.log(this);
};

var o = {
f1: function () {
 console.log(this);
 var f2 = temp();
}
}

用一个变量保存一个函数地址,函数运行时的环境是全局的。在严格模式下,如果函数内部的this指向顶层对象,就会报错。

2.如果this所在的方法不在对象的第一层,这时this只是指向当前一层的对象,而不会继承更上面的层。

var a = {
  p: 'Hello',
  b: {
    m: function() {
      console.log(this.p);
    }
  }
};

a.b.m() // undefined
call,apply,bind三种方式绑定this
var n = 123;
var obj = { n: 456 };

function a() {
  console.log(this.n);
}

a.call() // 123
a.call(null) // 123
a.call(undefined) // 123
a.call(window) // 123
a.call(obj) // 456

call方法的参数,应该是一个对象。如果参数为空、nullundefined,则默认传入全局对象。

如果call方法的参数是一个原始值,那么这个原始值会自动转成对应的包装对象,然后传入call方法。

var f = function () {
  return this;
};

f.call(5)
// Number {[[PrimitiveValue]]: 5}

apply方法的作用与call方法类似,也是改变this指向,然后再调用该函数。唯一的区别就是,它接收一个数组作为函数执行时的参数

函数执行时的参数,使用格式如下。

func.apply(thisValue, [arg1, arg2, ...])
常用的方法
  1. 找出数组最大元素

    JavaScript 不提供找出数组最大元素的函数。结合使用apply方法和Math.max方法,就可以返回数组的最大元素。

    var a = [10, 2, 4, 15, 9];
    Math.max.apply(null, a) // 15
    
  2. 将数组空元素变为undefined

    Array.apply(null, ['a', ,'b'])
    // [ 'a', undefined, 'b' ]
    

空元素与undefined的差别在于,数组的forEach方法会跳过空元素,但是不会跳过undefined。因此,遍历内部元素的时候,会得到不同的结果。

​ 3.转换类似数组的对象

Array.prototype.slice.apply({0: 1, length: 1}) // [1]
Array.prototype.slice.apply({0: 1}) // []
Array.prototype.slice.apply({0: 1, length: 2}) // [1, undefined]
Array.prototype.slice.apply({length: 1}) 

利用数组对象的slice方法,可以将一个类似数组的对象(比如arguments对象)转为真正的数组。

上面代码的apply方法的参数都是对象,但是返回结果都是数组,这就起到了将对象转成数组的目的。从上面代码可以看到,这个方法起作用的前提是,被处理的对象必须有length属性,以及相对应的数字键。

bind方法
var counter = {
  count: 0,
  inc: function () {
    this.count++;
  }
};

var func = counter.inc.bind(counter);
func();
counter.count // 1

​ 如果直接运行func函数运行环境是window,this指向window,使用bind,修改运行环境对象为counter.

function add(x, y) {
  return x + y;
}

var plus5 = add.bind(null, 5);
plus5(10) // 15

add函数没有this指向,第一个参数可以不要,也可以是其他对象,然后指定了第一个参数默认x默认为5,调用时只需传第二个参数y即可。

注意点:

1.bind()方法每运行一次,就返回一个新函数。apply和call方法都是立即执行函数。所以点击事件不能直接绑定bind方法,否则点击一次产生一个匿名函数,无法取消绑定。以下代码就不行。

element.addEventListener('click', o.m.bind(o));
element.removeEventListener('click', o.m.bind(o));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值