eg:var Tdog={name=“Tdog”,age=18,intro=function(){
console.log(‘I’m ${this.name},I’m ${this.age}’);}}
Tdog.intro();
在Tdog中调用intro()方法时,会先进入Tdog对象中寻找intro,然后根据Tdog的地址找到intro,intro()在调用时会开辟一个局部作用域,并且会形成一个二级作用域链,也就是local和window。
在没有加this的情况下:
程序首先会在local里找变量name和age,因为没有var这两个变量,所以找不到。于是再到window里去找,而window里的全局变量只有一个,即Tdog。程序也不能在没有指令的情况下贸然进入任何对象。于是报错。
在没有加this,但是加了Tdog的情况下:
程序执行正确,但是一旦当对象名Tdog修改,方法里的Tdog也得跟着一块修改,否则找不到。形成了紧耦合的状态。
加this的情况:
每个函数与生俱来都有this关键词,可以自动获得.前的对象。例如Tdog.intro()发生时,intro里的this.name和this.age方法intro会自动进入Tdog内查找,因为是Tdog调用的intro(),于是this就指向了Tdog。即使Tdog改名,方法里.前的名字也不用改。这就是松耦合。
this只和调用时.前的对象有关,和保存在哪无关:
eg:var intro=Tdog.intro;
*此时intro后面没有加()就不是调用,而是给:Tdog对象是引用类型,无法保存于本地,只能以地址的形式找到。所以window里只能存下一个Tdog名,而Tdog只是把intro的地址给了给了全局变量里的intro,他俩共用一个intro的地址。intro只存在于window之外的那一个地方。intro()是window.intro()直接根据地址找到intro,只是window下没有name和age的变量,程序只会输出undefined,不会报错。如果name和age前面没有this.或者Tdog.那么会报错,因为这个时候程序查找的是变量而不是从对象里找属性。这里引出了一个原理:js底层都是关联数组。访问对象里不存在的属性时不会报错,只会返回undefined。
在其他的语言里new object之后就定了,不能再往里加属性方法,而在js里是可以的,就像数组一样不停往里添加元素。并且有两种不同的方法:对象.属性 or 对象[属性]
var fun=function(){}
Tdog.fun=fun;
Tdog里本不存在fun这个方法,但是全局里的fun把地址告诉了Tdog,于是Tdog知道了fun的地址。就也能通过地址找到fun,也就是等于拥有了fun。
函数前没有加.的是全局函数,所以this指向的是window。
方法存在什么地方不重要,重要的是.前面的对象是谁。
只要对象在自己的方法内,想使用对象自己的属性和其他方法时,都必须用this。