构造函数模式

ECMAScript中的构造函数可用来创建特定类型的对象,像Object和Array这样的原生构造函数。
也可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法。

1.创建对象

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.showName = function(){
        console.log("name = " + this.name);
    };

}

var p1 = new Person("Mike", 20, "student");
var p2 = new Person("Tom", 23, "student");

console.log(p1);
console.log(p2);

图片描述

与工厂模式的区别:

  • 没有显示地创建对象

  • 直接将方法和属性付给了this对象

  • 没有return语句

构造函数应该始终以一个大写字母开头。

创建构造函数的实例,必须使用new操作符。以这种方式调用构造函数,会经历以下4个步骤:

  • 创建一个新对象;

  • 将构造函数中的作用域赋给新对象(this就指向了这个对象)

  • 执行构造函数中的代码(为这个新对象添加属性)

  • 返回新对象

对象有一个constructor用来标识对象类型。p1和p2对象,都有一个constructor(构造函数)属性,该属性指向Person。

console.log("p1.constructor=");
console.log(p1.constructor);
console.log("p1.constructor === Person:");
console.log(p1.constructor === Person);
console.log("p2.constructor=");
console.log(p2.constructor);
console.log("p2.constructor === Person:");
console.log(p2.constructor === Person);

图片描述

但是,提到检测对象类型,还是instanceof操作符要更可靠些。Person构造函数创建的所有对象,既是Object的实例,也是Person的实例。

console.log("p1 instanceof Object:");
console.log(p1 instanceof Object);
console.log("p1 instanceof Person:");
console.log(p1 instanceof Person);
console.log("p2 instanceof Object:");
console.log(p2 instanceof Object);
console.log("p2 instanceof Person:");
console.log(p2 instanceof Person);

图片描述

2.观察Person构造函数涉及到的原型链

console.log("Person.prototype=");
console.log(Person.prototype);
console.log("Person.prototype === Function.prototype;");    
console.log(Person.prototype === Function.prototype);    //false
console.log("-----分割线-----");

console.log("Person.prototype.constructor === Person:");    //true
console.log(Person.prototype.constructor === Person);    //true
console.log("-----分割线-----");

console.log("Person.prototype.__proto__ === Object.prototype:");    //true
console.log(Person.prototype.__proto__ === Object.prototype);    //true
console.log("-----分割线-----");


console.log("Person.__proto__=");
console.log(Person.__proto__);
console.log("Person.__proto__ === Function.prototype:");
console.log(Person.__proto__ === Function.prototype);    //true
console.log("-----分割线-----");

图片描述

3.观察p1实例对象涉及到的原型链

console.log("p1.prototype=");
console.log(p1.prototype);
console.log("-----分割线-----");

console.log("p1.__proto__=");
console.log(p1.__proto__);
console.log("p1.__proto__ === Person:");
console.log(p1.__proto__ === Person);        //false
console.log("p1.__proto__ === Person.prototype:");
console.log(p1.__proto__ === Person.prototype);        //true
console.log("-----分割线-----");

console.log("p1.__proto__.constructor === Person:");
console.log(p1.__proto__.constructor === Person);
console.log("-----分割线-----");

console.log("p1.__proto__.__proto__=");
console.log(p1.__proto__.__proto__);
console.log("p1.__proto__.__proto__ === Object.prototype:");
console.log(p1.__proto__.__proto__ === Object.prototype);    //true
console.log("-----分割线-----");

图片描述

4.观察下p1.showName属性引用的函数

console.log("p1.showName.prototype=");
console.log(p1.showName.prototype);

console.log("p1.showName.prototype  === Function.prototype:");    
console.log(p1.showName.prototype  === Function.prototype);    //false
console.log("-----分割线-----");

console.log("p1.showName.prototype.constructor=");
console.log(p1.showName.prototype.constructor);
console.log("-----分割线-----");

console.log("p1.showName.prototype.__proto__=");
console.log(p1.showName.prototype.__proto__);

console.log("p1.showName.prototype.__proto__ === Object.prototype:");    
console.log(p1.showName.prototype.__proto__ === Object.prototype);    //true
console.log("-----分割线-----");

console.log("p1.showName.__proto__=");
console.log(p1.showName.__proto__);
console.log("p1.showName.__proto__ === Function.prototype:");    
console.log(p1.showName.__proto__ === Function.prototype);    //true
console.log("-----分割线-----");

图片描述

原型链图

图片描述


small2
1.5k 声望95 粉丝

海潮迷