js里,一切皆对象,但有普通对象和函数对象之分,通过new Function()创建的对象就是函数对象。
- 原型对象:
每个对象都有 ___proto____ 属性,但只有函数对象才有 prototype 属性。
每个函数对象都有一个prototype属性,这个属性指向函数的原型对象(prototype),因此其实原型对象(Person.prototype)是 构造函数(Person)的一个实例,也就是一个普通对象,具备普通对象的一切特性,但是,需要强调下Function.prototype是个函数对象,因为函数对象的实例也是个函数对象,并不是普通对象。原型对象主要是用来继承的.
在默认情况下,所有的原型对象都会自动获得一个 constructor(构造函数)属性,这个属性(是一个指针)指向 prototype 属性所在的函数(Person),换成代码的意思就是Person.prototype.constructor == Person。
- ___proto____:
JS 在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做proto 的内置属性,用于指向创建它的构造函数的原型对象。
对象 person1(Person对象的实例) 有一个 proto属性,创建它的构造函数是 Person,构造函数的原型对象是 Person.prototype ,所以:
Person.prototype.constructor == Person;
person1.__proto__ == Person.prototype;
person1.constructor == Person;
不过,要明确的一点,上面这个连接存在于实例(person1)与构造函数(Person)的原型对象(Person.prototype)之间,而不是存在于实例(person1)与构造函数(Person)之间。
提示:因为绝大部分浏览器都支持___proto____属性,所以它才被加入了 ES6 里。
Object.prototype.__proto__==null
,这里这个为null,比较特殊,它是原型链的顶端。 - 函数对象:
所有函数对象的__proto____都指向Function.prototype,它是一个空函数(Empty function)。而Function.prototype的___proto____是这样的:
Function.prototype.__proto__ === Object.prototype
。这说明所有的构造器也都是一个普通 JS 对象,可以给构造器添加/删除属性等。同时它也继承了Object.prototype上的所有方法:toString、valueOf、hasOwnProperty等。
写原型有两种写法区别:
修改原型:Person.prototype.getName = function() {}
;
重写原型:Person.prototype = { getName: function() {} }
;
区别在与第二种是使用对象直接量(直接量也称为字面量,是JavaScript中一种对象的表示(或者说创建)方式,它可以通过直接给变量赋上JavaScript中原生对象值的方式从而转换为一个相应的对象)方式,这种方式定义的对象,它的构造器(constructor)指向的是根构造器Object。