javascript语言是在运行时前即进行编译的,而this的绑定也是在运行时进行绑定的。也就是说,this其实是在函数被调用时候发生绑定的,它指向什么彻底取决于函数在哪里被调用。
1.默认绑定javascript
例如直接在全局做用域下声明:java
var a=2; console.log(this.a);
以致于你运行如下的代码片断:
function foo(){ console.log(this.a); } var a=2; foo();
浏览器控制台打印出来的是 2 ;
2.隐式绑定程序员
当函数引用有上下文对象时,在函数调用时,会进行隐式绑定。这么说确定很抽象,仍是举例说明吧。
var a=4; function foo(){ console.log(this.a); } var obj={ a:2, foo:foo } foo(); obj.foo();
两次会打印出来什么呢?猜一下?
3.显式绑定浏览器
在上面两种绑定中,咱们都没有去明确地进行强制绑定,而是使用了默认规则的绑定,那么若是咱们想要在调用某个函数时特定地改变this的绑定,这个时候就能够用显式绑定了。
仍是上代码,而后进行分析。app
var a=4; function foo(){ console.log(this.a); } var obj={ a:2, foo:foo } var foo1=foo.bind(obj); foo(); foo.call(obj); foo.apply(obj); foo.call(window); foo1();
按照顺序打印出的是 4 ,2 ,2, 4,2
4.new 绑定框架
使用new方式进行调用函数时,会发生构造函数的调用。怎么解释呢,仍是直接上代码加分析。
function foo(a){ this.a=a; } foo(3); var test=new foo(2); console.log(a); console.log(test.a);
打印出来的是 3 ,2
先上图,而后根据文字阅读
使用new 调用函数以后,该foo函数才做为构造函数进行调用,构造一个全新的对象赋值给test,而test对象的_proto_
指向了test的prototype对象,test的prototype对象有一个属性constructor,指向test的构造函数foo,这个就是javascript的原型链,也是javascript的特性。对于test对象调用的方法以及属性,会先在test对象进行寻找,若是找到的话,就直接进行调用,寻找中止。若是寻找不到,顺着原型链,在test对象的prototype对象寻找,若是找到的话,进行调用,寻找中止,若是仍是找不到,会在prototype对象的原型上进行寻找,这个时候_proto_指向了Object的prototype对象,Object的prototype的constructor指向了Object()自己,而一些Obejct的函数如toString等等就是在这个原型上进行调用的,这个时候若是仍是找不到须要属性或者方法,那么就是语法错误,未定义了。由于Object的prototype的_proto_指向是null了,也就没有任何对象属性以及方法了。不是说程序员能够new 不少个对象嘛,可是new出来的对象 原型最终结果倒是指向了 空(null),因此仍是本身动手丰衣足食吧,哈哈。函数
通常状况下,使用new函数以后构造的对象,会优先将函数调用到的this绑定到这个对象,若是函数没有返回其它对象,会自动调用返回这个新对象。this
总结:编码
只有对于this绑定的状况有了基本的了解,才能在编写代码时候,避免产生因为绑定带来的未知bug。若是你在调用某个框架插件或者绑定事件的时候,发现this很差用了,有多是你的this使用绑定错了,打印下console.log(this)在控制台看一看,也许就发现问题了。若是在阅读中遇到什么问题,欢迎评论以及留言。同时欢迎个人博客陈建光的博客spa
欢迎评论以及留言,同时欢迎关注个人博客定时不断地更新个人文章 陈建光的博客