面向对象精要-构造函数和原型对象
1、构造函数
function Person() { }
构造函数-----首字母大写
1.1、实例化对象
function Person() { } var person1 = new Person()
1.2、检测对象类型
instanceof 方法
function Person() { } var person1 = new Person(); console.log(person1 instanceof Person);/*true*/
constructor 方法
function Person() { } var person1 = new Person(); console.log(person1.constructor === Person);/*true*/
建议使用instanceof检测对象类型,因为构造函数属性可以被覆盖,并不一定完全准确。
2、原型对象
原型对象好比对象的基类。
几乎所有的函数都有一个名为prototype的属性,该属性数一个原型对象用来创建新的对象实例。
2.1、[[Prototype]]属性
实例对象的内部属性,跟踪到原型对象。
指向该实例使用的原型对象的一个指针。
读取方法:
Object.getPrototypeOf()
function Person() { } var person1 = new Person(); var prototype = Object.getPrototypeOf(person1); console.log(prototype === Person.prototype)/*true*/
大部分引擎在所有对象上都支持一个名为__proto__的属性。该属性可以直接读写[[Prototype]]属性。
2.2、在构造函数中使用原型对象
function Person(name) { this.name = name; } Person.prototype.sayName = function () { console.log(this.name) }; var person1 = new Person("Qian"); var person2 = new Person("Wei"); person1.sayName(); //Qian person2.sayName(); //Wei
sayName()现在是一个原型属性而不是自有属性
添加多个属性,简洁的方法
function Person(name) { this.name = name; } Person.prototype = { sayName:function () { console.log(this.name) }, toString:function () { return "[Person "+this.name+"]" } }; var person1 = new Person("Qian"); person1.sayName();/*Qian*/ console.log(person1.toString());/*[Person Qian]*/
副作用
function Person(name) { this.name = name; } Person.prototype = { sayName:function () { console.log(this.name) }, toString:function () { return "[Person "+this.name+"]" } }; var person1 = new Person("Qian"); person1.sayName();/*Qian*/ console.log(person1.toString());/*[Person Qian]*/ console.log(person1 instanceof Person);/*true*/ console.log(person1.constructor === Person);/*false*/ console.log(person1.constructor === Object);/*true*/
使用对象字面量形式改写原型对象改变了构造函数的属性,因此他现在指向Object而不是Person。
原因:原型对象具有一个constructor属性,这是其他对象实例所没有的,当一个函数被创建时,它的prototype属性也被创建,且该原型对象的constructor属性指向该函数。当使用对象字面形式改写原型对象的Person.prototype时,其constructor属性将被置为泛用对象Object()。
解决办法:需要在改写原型对象时手动重置为constructor属性
function Person(name) { this.name = name; } Person.prototype = { constructor:Person, sayName:function () { console.log(this.name) }, toString:function () { return "[Person "+this.name+"]" } }; var person1 = new Person("Qian"); person1.sayName();/*Qian*/ console.log(person1.toString());/*[Person Qian]*/ console.log(person1 instanceof Person);/*true*/ console.log(person1.constructor === Person);/*true*/ console.log(person1.constructor === Object);/*false*/
2.3、内建对象的原型对象
Array.prototype.sum = function () { return this.reduce(function (pre,cur) { return pre+cur; }); }; var number = [1,2,3,4,5]; console.log(number.sum())/*15*/
在Array.prototype上创建一个名为sum()方法。