说实话,js之前没有系统学过,基础还是很薄弱。。。今天看到了一段代码,有些难以理解,抽象出来是这样的
class A{
constructor(){
this.name="tom";
this.age=19;
}
getAge()
{
console.log('age is '+this.age);
}
f()
{
this.getAge();
}
}
我当时心里的第一想法就是:为什么函数f里面调用getAge要加this?是不是多余了?
最近在看红宝书,书里写的是:对于class来说, constructor构造函数里定义的,都是实例属性,类块中定义的方法,是加载实例的原型上的方法,所有实例可以共享。
既然如此,getAge方法已经加在了A的实例a中,那么调用a.f(),要是不加this直接调用getAge,会沿着原型链去a的原型上找到getAge啊,this岂不是多余的?
然后创造实例调用之后,就会报错
class A{
constructor(){
this.name="tom";
this.age=19;
}
getAge()
{
console.log('age is '+this.age);
}
f()
{
getAge();
}
}
let a=new A();
a.f();
错误信息:
报错很明显的说了,getAge找不到,为什么会找不到?来仔细分析一下。
前面说到:getAge方法已经加在了A的实例a中,那么调用a.f(),要是不加this直接调用getAge,会沿着原型链去a的原型上找到getAge啊,this岂不是多余的?
关键就在于不加this直接调用。this指向的是谁?指向的是a对象,this.getAge(),意思是,如果a对象上找不到getAge,那么就去a的原型上找,显然a的原型上有getAge。
可是不加this呢?不加this,函数getAge被调用,由于函数f中没有定义getAge,因此会报错。
函数f中没有定义getAge,那么类A中定义了getAge了啊,为什么不去类A中找呢?因为类A中的getAge是加在A.ptototype这个对象上的,不是在A中。
附上一个js中查找的规则:
1. 直接通过标识符访问变量,首先沿着作用域链查找每一个变量对象,直到全局变量对象(window)仍没有,就沿着全局变量对象(window)的原型链查找
2. 通过 . 或 [] 访问对象中的标识符,就直接沿着原型链查找