/**
* 构造函数模式
* 1、与工厂模式相比
* a、没有显示的创建对象
* b、直接将属性和方法赋给了构造函数的 this 对象
* c、没有 return 语句
*
* 2、直接调用构造函数时,构造函数与普通函数无异
* this 指向调用该函数的最后一个对象
*
* 3、构造函数的缺点
* 每个方法都要在每个实例上重新创建一遍,即每个实例的同名方法都不同一个方法
* 即 c1.speak != c2.speak
*/
function Constructor (name, sex, job) {
this.name = name
this.sex = sex
this.job = job
// this.speak => new Function('console.log("hello...")')
this.speak = function () {
console.log('hello...')
}
}
/**
* 1、创建构造函数对象必须使用 new 操作符,new 操作符的四个步骤为
* a、创建一个新的对象
* b、将构造函数的作用域赋给新对象(因此 this 就指向了新对象)
* c、执行构造函数中的代码(为这个新对象添加属性)
* d、返回新对象
*
* 2、生成的实例对象都有一个 constructor(构造函数) 属性,该属性指向构造函数
* 生成的实例对象即是构造函数 Constructor 的实例,也是构造函数 Object 的实例
*/
const c1 = new Constructor('tang', 'man', 'web design')
const c2 = new Constructor('chen', 'womam', 'teacher')
console.log(c1)
console.log(c2)
// true,实例对象是构造函数 Constructor 的实例
console.log(c1 instanceof Constructor)
// false,实例对象不是构造函数 Function 的实例
console.log(c1 instanceof Function)
// true,实例对象也是对象 Object 构造函数的实例(对象均继承自 Object)
console.log(c1 instanceof Object)
/**
* 构造函数直接调用
*/
const o = new Object()
Constructor.call(o, 'chen', 'womam', 'teacher')
console.log(o)
/**
* 每个同名方法在实例上都会被重新创建
*/
const c3 = new Constructor('tang', 'man', 'web design')
const c4 = new Constructor('chen', 'womam', 'teacher')
console.log(c3.speak == c4.speak) // false
/**
* 对于缺点的改进方法,设置了一个全局的函数,但也有新的问题
* 1、若对象需要定义多个方法,则需要创建多个全局函数,没有封装性可言
*/
function ConstructorMethod (name, sex, job) {
this.name = name
this.sex = sex
this.job = job
this.speak = speak // 相当于指向到了一个地址的指针
}
// 全局函数
function speak () {
console.timeLog('hello...')
}
const m1 = new ConstructorMethod('tang', 'man', 'web design')
const m2 = new ConstructorMethod('chen', 'womam', 'teacher')
console.log(m1.speak === m2.speak) // true
网友评论