疑问:
为什么js中基本类型变量和函数都能够像对象一样可以访问属性。这是因为js中它们都具有这个对象特性,但是跟对象的区别主要在于,是否可以对属性进行赋值。
基本属性:
1、constructor:创建实例的构造函数。除了underfined、null,其他通过new生成或者字面量创建的变量都有该属性。基本类型变量该属性值不可修改。
构造函数拓展:字面量就是构造函数的语法糖。
2、proto:隐式原型,指向创造实例的构造函数的原型。
3、prototype:函数才有这个属性,实例的原型,原型里有两个属性,a、constructor:指向函数本身;b、proto:指向构造函数的prototype。
重点:
Object instanceof Function => true;Function instanceof Object => true;
其他的构造函数如:Array、Boolean、String包括Object的prototype都是有constructor、proto和其他的属性的。就是Function的prototype输出就是fn(){native code}。按照有类这种概念的语言中的理解。Function的prototype就是有真正的类的功能,但是它不是一个类。所以跟其他语言的类还是有区别的。因为Function等其他构造函数都可以使用toString等方法,这些都是继承于Object这个类的。所以按照其他语言的理解,Object还是很大程度上符合了类的抽象性的特点的。里面有抽象的公用的属性和方法。不同的是其他语言的类的属性的方法是直接定义在构造函数里的,而js中的是给构造函数定义了一个prototype属性,公用的方法是定义在了prototype中了。同时还定义了一个constructor属性,指向了构造函数自身。我的感觉就像是构造函数是空的,然后弄了prototype属性来放原本应该放在构造函数中的属性和方法。prototype才是真正的控制者,构造函数就是个傀儡。这个prototype属性中的constructor的作用是什么呢?因为实例本身是没有constructor属性的,属性放在了prototype原型中,也就是可以被继承,constructor被继承的作用是实例可以知道创建自己的构造函数。proto被继承的作用是实例可以访问构造函数的原型(prototype),也就是访问到真正的属性和方法的持有者,即:父类。这样就实现了继承。而字面量创建的变量实际它的构造函数就是原始的构造函数,而不是继承了好几代的。也即:let num = Number();num.proto === Number.prototype; 我之前是完全晕头转向。
总结:
1、js中的原型跟其他**语言中**类概念的区别是:类有的属性和方法就放在构造函数里。而原型(prototype)才是真正的拥有者。构造函数只是一个傀儡。原型是对象,可能是js中比较强调对象的原因吧。
2、函数(第一公民)才有prototype属性,其他只有proto属性代替。其中实例直接引用的constructor。而是查找原型链使用的。prototype存放了constructor和proto属性。constructor实现实例知道产生自己的构造函数,proto实现属性方法继承。
3、Function.prototype,实现了函数,Object.prototype实现了类和继承。
