要点
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象。
this指向的三种情况
情况1:如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版中this指向的不是window,而是指向调用函数的对象实例,这种函数中的this等于undefined。
function a(){
var user = "维他奶";
console.log(this);//window
console.log(this.user);//undefined
}
//windonw是全局对象,所有的全局变量都是对象的属性.
//a()<=>window.a()
a();
console.log(window);
console.log(window.user);//根本没有user这个属性。只有一个name="";
运行结果
严格模式,请参照https://segmentfault.com/a/11...
严格模式下定义变量必须使用var。否则报错.
在严格模式下,对象的函数中的this指向调用函数的对象实例
同样道理,可以推断出,在严格模式下,构造函数中的this指向构造函数创建的对象实例。
"use strict";//开启严格模式
function a(){
var user = "维他奶";
//在严格模式下,对象的函数中的this指向调用函数的对象实例
console.log(this);//a{}
console.log(this.user);//undefined
}
var A = new a();
运行结果
情况2:如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。
var sum = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a);//12
}
}
}
sum.b.fn();
运行结果
情况3:如果一个函数中有this,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象.
var sum = {
a:10,
b:{
// a:12,
fn:function(){
console.log(this.a);//undefined
}
}
}
sum.b.fn();
运行结果
注意事项
尽管对象b中没有属性a,这个this指向的也是对象b,因为this只会指向它的上一级对象,不管这个对象中有没有this要的东西。
情况4:this永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,情况4中虽然函数fn是被对象b所引用,但是在将fn赋值给变量num的时候并没有执行所以最终指向的是window,这和情况3是不一样的,情况3是直接执行了fn。
var sum = {
a1:10,
b:{
a:12,
fn:function(){
console.log(this.a1);//undefined
console.log(this);//window
}
}
}
var num = sum.b.fn;
num();
运行结果
构造函数的this指向:
function A(){
this.name = "维他奶";
}
var a = new A();
console.log(a.name);//维他奶
运行结果
new关键字到底做了什么?
(1) 创建一个新对象;
(2) 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象);原理:自动调用apply方法,将this指向这个空对象,这样的话函数内部的this就会被这个空的对象替代。
(3) 执行构造函数中的代码(为这个新对象添加属性);
(4) 返回新对象。
return 会把new创建的this覆盖.
如果返回值是复杂数据类型,那么this指向的就是那个返回的对象,如果返回值不是复杂数据类型那么this还是指向函数的实例。
function A(){
this.name = "维他奶";
return 1;
}
var a = new A();
console.log(a.name);//维他奶
function A(){
this.name = "维他奶";
return ;
}
var a = new A();
console.log(a.name);//维他奶
function A(){
this.name = "维他奶";
return function(){};
}
var a = new A();
//传入空函数,所以输出一个空,而不是undefined
console.log(a.name);//""
function A(){
this.name = "维他奶";
return null;
}
var a = new A();
console.log(a.name);//维他奶
简单数据类型:string,boolean,number,undefined,null,NaN
复杂数据类型: Object,Function,Array,String,Boolean,Number
其中String,Boolean,Number,是自带的封装好的方法。
简单数据类型存放在内存的栈中,而复杂数据类型存放在内存的堆中,把地址存放在内存的栈中,先获取地址,再读取堆中数据。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。