面向对象精要-构造函数和原型对象

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()方法。

posted @ 2018-04-18 22:19  BluesQian  阅读(267)  评论(0编辑  收藏  举报