w3ctech

this的前世今生

this的前世今生

this为何物

在js中每个函数都有内部属性this以及arguments,其实函数本身也是有属性的(函数本身就是Function的实例,记住只有对象才具有属性),一般来说,函数本身具有5个属性(name,arguments,prototype,caller,length)

//自定义的函数  
function foo(){}  
console.log(Object.getOwnPropertyNames(foo));

自定义的函数

//js中自带的函数Window  
console.log(Object.getOwnPropertyNames(Window));

js中内置的函数
其实我觉得this表示的是函数执行过程的上下文环境,this绑定的方法含有4种方法,首先介绍默认绑定(直接使用不带任何修饰的函数引用进行调用的,使用严格模式,全局对象就无法使用默认绑定)以及隐式绑定(调用位置是否有上下文,或者说是是否被某个对象拥有或者包含)

function say(name){
   this.name = name;
   console.log(this.name);
   console.log(this);//打印出this对象
}
say("vicco");//默认绑定

say函数中this指向的是window对象
默认绑定

var obj = {
   name : "苍老师",
   speak : function(){
      console.log("Hello My name is "+this.name);  
   }
};
obj.speak();//隐式绑定

其实可以发现这两种this绑定的方式可以调用栈和调用位置来进行理解
调用栈(为了到达当前执行位置调用的所有函数)
调用位置(在当前正在执行函数的前一个调用中)
比较难以理解两个名词,可以用代码解释

function say(){
   console.log(this.name);
}
say();//默认绑定

默认绑定解释
另外为什么输出this.name为空字符串,这是因为this.name等价于window.name,用来标明窗口的名字,如果最顶层窗口不是使用window.open()打开的话,其window.name为空字符串(ps:其指的是顶层窗口还是窗口中的frame或者iframe,待实验验证)

var obj = {
   name : "苍老师",
   speak : function(){
      console.log("Hello My name is "+this.name);  
   }
};
obj.speak();//隐式绑定

隐式绑定解释
隐式缺失*(我更喜欢称为"披着羊皮的狼")*

第一种情况

第二种情况

第三种情况

显式绑定

new绑定

w3ctech微信

扫码关注w3ctech微信公众号

共收到5条回复

  • 第一个问题:foo中调用arguments,其实就是调用foo.arguments 所以在foo这个函数中arguments = foo.arguments

    回复此楼
  • @beggarWang 其实当你函数内部里面还有函数,这时候foo.arguments是有必要的,如果你在内部函数里面直接使用arguments表示的是该函数调用时实参

    回复此楼
  • @beggarWang 函数的的生命周期分为创建和激活阶段(调用时) 创建阶段:将函数声明放到变量对象中,同时声明arguments(类数组的对象Object),此时arguments=[]【此过程是js内部运行机制,不可控】 激活阶段:给变量对象中的声明变量赋值,同时给arguments添加属性

    回复此楼
  • @刘亮爱雪薇 对的,内部函数可以调用外部函数的实参

    回复此楼
  • 终于理解了为什么定时器函数中this的指向会变为window了。

    回复此楼