this的指向在函数定义的时候是肯定不了的,只有函数执行的时候才能肯定this到底指向谁,实际上this的最终指向的是那个调用它的对象。segmentfault
状况1:若是一个函数中有this,可是它没有被上一级的对象所调用,那么this指向的就是window,这里须要说明的是在js的严格版中this指向的不是window,而是指向调用函数的对象实例,这种函数中的this等于undefined。app
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指向构造函数建立的对象实例。this
"use strict";//开启严格模式 function a(){ var user = "维他奶"; //在严格模式下,对象的函数中的this指向调用函数的对象实例 console.log(this);//a{} console.log(this.user);//undefined } var A = new a();
运行结果spa
状况2:若是一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。code
var sum = { a:10, b:{ a:12, fn:function(){ console.log(this.a);//12 } } } sum.b.fn();
运行结果对象
状况3:若是一个函数中有this,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象.blog
var sum = { a:10, b:{ // a:12, fn:function(){ console.log(this.a);//undefined } } } sum.b.fn();
运行结果ip
注意事项
尽管对象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();
运行结果
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,是自带的封装好的方法。简单数据类型存放在内存的栈中,而复杂数据类型存放在内存的堆中,把地址存放在内存的栈中,先获取地址,再读取堆中数据。