Prototype和proto联系
在JavaScript中,万物皆对象,对象都有原型。
(不太严谨:应该说,不是对象就是原始类型;除了base object,其他对象都有原型。)
所有的对象都有一个属性,叫proto( __proto __)。
prototype是函数这类特殊的对象,特有的属性
proto和prototype都是一个对象。
__proto__是真正用来查找原型链去获取方法的。
这里的函数Person可以获取到toStrinng、call、bind方法,这些方法是JavaScript引擎内置的。
prototype是在用new一个对象时构建__proto__的
本身是空的,通过Person.prototype.city = xian设置公用的属性;Person.prototype.sleep = function(){... } 设置公用的方法
对象的实例化可以是var ming = new Person(xiaoming)
也可以是var ming = Object.create(Person.prototype)
通常只有在一个函数被用作构造函数时,才会往这个空的对象里加一些东西。
function Person(firstname, lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
Person.prototype.getFullName = function() {
return this.firstname + ' ' + this.lastname;
}
var brynn = new Person('Brynn', 'Brown');
console.log(brynn);
console.log(brynn.getFullName());
var boolean = new Person('Boolean', 'White');
console.log(boolean);
console.log(boolean.getFullName());
可以看到,brynn和boolean这两个对象并没有直接拥有方法getFullName。
但它们都可以调用这个方法,因为他们都存在于person这个构造函数的prototype中,用person这个构造函数生成的所有对象,它们的原型(__ proto __)都是person的prototype。
也就是
brynn的__proto__中。
当然,我们完全可以将getFullName作为一个method写到Person这个function中,但这样会浪费空间——如果有100个"Person",就需要100块内存放100个getFullName方法。
但这没必要,方法不像属性,方法可以写成一模一样的。
将getFullName写到Person这个构造函数的prototype中,100个"person"就只需要一块内存来放这个getFullName方法。
所以,构造函数中往往是属性,构造函数的prototype中才是方法,这也是为什么叫prototype chain,不叫proto chain.