this的取值是执行上下文环境的一部分,每次调用函数,都会产生一个新的执行上下文环境。当你在代码中使用了 this,这个 this的值就直接从执行的上下文中获取了,而不会从作用域链中搜寻。
1.全局的this指向window
在全局情况下this永远指向window;
1console.log(this===window)//true普通函数调用的时候this也是指向window(注意严格模式下为undefined)
123456var x = 10; //window.xfunction foo(){console.log(this); //windowconsole.log(this.x); //10}foo(); //foo.call(window),window.foo()
2.对象方法
如果函数作为对象的方法来调用的时候,this指向调用它的该对象
123456789注意这里声明用的不是let,所以obj没有自己的块级作用域;var obj = {x: 10,foo: function () {console.log(this); //{x: 10, foo: ƒ}console.log(this.x); //10}};obj.foo();如果在对象方法中定义函数,那么也就是闭包,this是会指向window
123456789101112var obj = {x: 10,foo: function () {console.log(this) //{x: 10, foo: ƒ}function f(){console.log(this); //Windowconsole.log(this.x); //10console.log(obj.x===window.x) //true,obj===window.obj}f();}}obj.foo();
函数虽然是在obj.foo中定义的,但它仍然只是个普通函数。作用域的特性,自己内部没有就会向父函数里找,父函数没有,就会向更上级找,直到最终找到或找不到为止。
- 如果foo方法不作为对象被调用,那么就指向调用它的那个123456789var obj = {x: 10,foo: function () {console.log(this); //Windowconsole.log(this.x); //10}};var fn = obj.foo; //window.fnfn();
3.构造函数
构造函数就是由一个函数 new 出来的对象,一般构造函数的函数名首字母大写,例如像 Object,Function,Array这些都属于构造函数。
如果函数作为构造函数使用,那么其中的 this 就代表它即将 new 出来的对象。
123456function Foo(){this.x = 10;console.log(this); //Foo {x:10}}var foo = new Foo();console.log(foo.x); //10但是如果直接调用 Foo 函数,而不是 new Foo(),这时候 Foo() 就变成普通函数。
123456function Foo(){this.x = 10;console.log(this); //Window}var foo = Foo();console.log(foo.x);//Uncaught TypeError: Cannot read property 'x' of undefined
4.构造函数的prototype属性
构造函数的prototype属性也就是原型对象。
在整个原型链中this代表的也是当前对象的值。
5.函数用call,bind,apply调用
|
|
call,bind,apply可以改变this的指向,this的值就取传入的对象的值。第一个参数如果为undefined,null或空就相当于是window。
6.箭头函数
函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
7.vue的this
注意,不应该使用箭头函数来定义 method 函数 (例如 plus: () => this.a++)。理由是箭头函数绑定了父级作用域的上下文,所以 this将不会按照期望指向 Vue实例,this.a将是 undefined。
为了弄清楚这个,我们先来弄懂这些:
- 我们在使用vue的时候总会先new vue({}),那么就是说vue其实是一个构造函数。
|
|
|
|
那么下面我们来看它源码:
|
|