1.工厂方式
var laughter = function () {
return '哈哈哈'
}
function parent() {
var children = new Object()
children.name = '小梁'
children.gender = 'female'
children.laughter = laughter
return children
}
var baby = parent()
console.log(baby.name) //小梁
console.log(baby.laughter()) //哈哈哈
说明:
1.在函数中定义对象,并定义对象的各种属性,,虽然属性可以为方法,但是建议将属性为方法的属性定义到函数之外,这样可以避免重复创建该方法
2.引用该对象的时候,这里使用的是 var x = Parent()而不是 var x = new Parent();因为后者会可能出现很多问题(前者也成为工厂经典方式,后者称之为混合工厂方式),不推荐使用new的方式使用该对象
3.在函数的最后返回该对象
4.不推荐使用这种方式创建对象,但应该了解
2.构造函数方式
var laughter = function () {
return '哈哈哈2'
}
function Parent () {
this.name = '小梁2'
this.gender = 'female2'
this.laughter = laughter
}
var baby = new Parent()
console.log(baby.name) // 小梁2
console.log(baby.laughter()) //哈哈哈2
说明:
1.与工厂方式相比,使用构造函数方式创建对象,无需再函数内部重建创建对象,而使用this指代,并而函数无需明确return
2.同工厂模式一样,虽然属性的值可以为方法,扔建议将该方法定义在函数之外
3..同样的,不推荐使用这种方式创建对象,但仍需要了解
3.原型方式
var laughter = function () {
return '哈哈哈3'
}
function Parent() {}
Parent.prototype.name = '小梁3'
Parent.prototype.gender = 'female3'
Parent.prototype.laughter = laughter
//或则下面这样写
// Parent.prototype = {
// name: '小梁3',
// gender: 'female3',
// laughter: laughter
// }
var baby = new Parent()
console.log(baby.name) // 小梁3
console.log(baby.laughter()) //哈哈哈3
说明:
1.函数中不对属性进行定义
2.利用prototype属性对属性进行定义
3.同样的,不推荐使用这样方式创建对象
4.混合构造函数和原型方式
function Parent() {
this.name = '小梁4'
this.gender = 'female4'
}
Parent.prototype.laughter = function () {
return '哈哈哈4'
}
var baby = new Parent()
console.log(baby.name) // 小梁4
console.log(baby.laughter()) //哈哈哈4
说明:
1.将所有属性不是方法的属性定义在函数中(构造函数方式)
将所有属性值为方法的属性利用prototype在函数之外定义(原型方式)
2.推荐使用这样方式创建对象.
5.动态原型方式
function Parent(name, gender) {
this.name = name
this.gender = gender
if(typeof Parent._say == 'undefined') { //**标记处1
Parent.prototype.sayName = function () {
return this.name
}
Parent._say = true //**标记处2
}
}
var baby1 = new Parent('小梁5')
var baby2 = new Parent('碳碳')
console.log(baby1.sayName ())
console.log(baby2.sayName ())
说明:
1.动态原型方式可以理解为混合构造函数,原型方式的一个特例
2.执行到【标记处2】就再也不执行【标记处1】第二次,因为此时此刻,Parent._say只是函数的属性,而不是函数对象的原型属性,如果是原型属性的话,new一个函数对象的实例,就会改变函数里面原型对象的属性,那么就会重复构造sayName 这个函数。正因为是这个原因,当Parent._say等于undefined的时候,执行一次sayName ,最后得到的Parent._say = true,这个时候改变的是函数的属性,而不是函数原型的属性,所以外部new一个对象实例根本无法改变函数的属性,从而保证创建该对象的实例时,属性的方法不会被重复创建!
3.推荐使用这种模式
6.寄生构造函数方式
function myArray() {
var value = new Array()
value.push.apply(value, arguments)
value.change = function () {
return this.join('/')
}
return value
}
var fruit = new myArray('apple','banana','pear')
console.log(fruit.change())
说明:
1.有时候我们并不想数组输出元素之间用“,”分割,于是我们采用join()方法;但是每定义一个引用类型都使用一次join()方法有点麻烦,那么解决这个问题的办法就是直接改变Array构造函数默认定义的输出方式, 类似Object,Array,Date等等的拥有原生构造函数的引用类型并不能直接修改其原生构造函数,那么此时寄生构造函数就派上用场了。
2.其实寄生构造函数就是在原生构造函数上的一个扩展,也就是你可以利用寄生构造函数来自定义一种引用类型,实现自己想要达到的效果。
7.稳妥构造函数方式
function Person(name,age,gender){
var obj = new Object();
obj.sayName = function(){
console.log(name)
};
return obj;
}
var person = Person("小梁",18,"female");
person.sayName();
说明:
1.稳妥即没有公共属性,而且其方法也不引用this对象,这种模式适应于一些安全环境中(禁止使用this和new),或防止数据被其他应用程序改动;
2.这里person中保存了一个稳妥对象,除了调用sayName()方法外,没有别的方式可以访问其数据成员。即使有其他代码会给这个对象添加方法或属性,但也不可能有别的办法访问传入到构造函数中的原始数据 。同样与寄生函数模式类似,使用稳妥构造函数模式创建的对象与构造函数之间也没有任何关系.