what's this???

目录
1.this究竟是什么
2.绑定this的方法
3.caller、arguments和callee

1.this究竟是什么

this总是指向一个调用当前属性或方法所在的对象,它在不同的运行环境(属性和方法的调用者)指向的环境(对象)不同,也就是说this的指向是动态的,但是无论this的指向是谁,只要清楚属性和方法的调用者是谁那么this就指向谁。

//在浏览器全局环境下,即window对象下
var print = function(){
      console.log(this)
 }
print()//this指向Window,因为这是Window对象调用了print方法

//在特定对象的环境下
var o = {
    print: function(){
      console.log(this)
  }
}
o.print()//this指向o,因为这是o对象调用print方法

2.绑定this的方法

this的动态切换,固然为JavaScript创造了巨大的灵活性,但有时,需要把this固定下来,避免出现意想不到的情况。JavaScript提供了call、apply、bind这三个方法,来切换/固定this的指向。

  • function.prototype.call()

函数实例的call方法可以指定函数内部this的指向,即函数执行时所在的作用域

var obj = {};
var fn = function(){
  return this
}
fn()  === this // true
fn.call(obj) === obj // true

fn()执行时所在的作用域是全局环境,所以this是window,而fn.call(obj)则是在对象obj环境下执行的,所以此时的this指向obj。

fn.call(null) === this
fn.call(undefined)  === this
fn.call === this 

call方法内部的参数如果为空、null和undefined,则默认传入全局对象。

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

add.call(obj,2,3)

call方法还可以接受多个参数。call的第一个参数就是this所要指向的那个对象,后面的参数则是函数调用时所需的参数。

  • function.prototype.apply()
    apply方法的作用与call方法类似,也是改变this指向,然后再调用该函数。唯一的区别就是,它接收一个数组作为函数执行时的参数。
function fn(x,y){
    return x+y
}

fn.call(null,1,1)//2
fn.apply(null,[1,1])//2

fn函数本来接受两个参数,使用apply方法以后,就变成可以接受一个数组作为参数。
【注】
结合apply和数组,我们可以写一个小代码找出数组最大或最小元素;

var arr = [3,5,7,10,2,8];

//未利用apply方法
var min = arr[0];
for (var i = 0;i
  • function.prototype.bind()
    bind方法用于将函数体内的this绑定到某个对象,然后返回一个新函数,原理和call方法类似。

3.caller、callee和arguments

  • caller
    当函数outer调用函数inner时,被调用的函数inner会自动生成一个caller属性,指向调用它的函数对象。
    如果该函数未被调用或是不是被其他函数调用,则caller为null。
function outer(){
  console.log(outer.caller);
  function inner(){
    console.log(inner.caller);
  };
  inner()
}
outer()
//null
//function outer(){}
  • arguments

在函数被调用时,会在该函数内部生成一个名为arguments的类数组的隐藏对象,可以使用[]运算符获取函数调用时传递的实参,只有函数被调用时,arguments对象才会创建。

function fn(a,b){
  console.log(arguments);
}
fn(1,2)//[1,2]
  • callee
    当函数被调用时,它的arguments.callee对象就会指向自身,由于arguments在函数被调用时才有效,因此arguments.callee在函数未调用时是不存在的。
function fn(){
  console.log(arguments.callee());
}
fn()//fn(){}

【注】
本次笔记整理自阮一峰JavaScript标准参考教程和饥人谷笔记

你可能感兴趣的:(what's this???)