面向对象模式
<script>
//1.工厂模式
function product(id ,name , desc){
var o = new Object();
o.id = id;
o.name = name;
o.desc = desc;
o.getname = function(){
alert(this.name)
}
return o;
}
var product1 = product("1", '包子', "描述:小笼包");
var product2 = product("2", '豆浆', "描述:豆浆");
//2.构造函数模式 (大写字母开头)
function User(name,mobile){
this.name = name;
this.mobile = mobile;
this.getname = function(){
alert(this.name)
}
}
var user1 = new User("Tom", "13000000000");
var user2 = new User("John", "13333333333");
alert(user1.constructor == User) //true
/*
1.没有显式创建对象
2.直接将属性和方法赋给了this对象
3.没有return语句
* */
/*
* 创建新的实例 new
* 1.创建了一个新的对象
* 2.将构造函数的作用域赋给新对象(this就会指向新对象)
* 3.执行构造函数中的代码(为新对象添加属性)
* 4.返回新对象
* */
/**
* 构造函数的问题:
* 每个方法都要在实例上重新创建一遍,不同实例上的同名函数是不相等的。
*
* */
alert(user1.getname == user2.getname )//false
function User(name,mobile){
this.name = name;
this.mobile = mobile;
this.getname = getname;
}
function getname(){
alert(this.name)
}
alert(user1.getname == user2.getname )//true
/**
* 把getname指向了全局作用域的getname函数,但是如果有很多方法就需要定义很多全局函数,这样就失去了封装性。
*/
//3.原型模式
/*
* 每个函数都有一个prototype(原型)属性,这是一个指针指向一个对象,这个对象可以包含所有实例共享的属性和方法
* */
function Product(){
}
Product.prototype.name = "包子";
Product.prototype.id = "123";
Product.prototype.desc = "描述:小笼包";
Product.prototype.getName = function(){
alert(this.name)
};
var product1 = new Product();
product1.getName(); //包子
var product2 = new Product();
alert(product1.getName == product2.getName)//true
//实例重写原型的属性
product1.name = '面包';
console.log(product1.name)
console.log(product2.name)
delete(product1.name)
console.log(product1.name)
console.log(product2.name)
//更简单的原型语法
function Product(){
}
Product.prototype = {
name : "套餐",
id : "123",
desc : "描述:套餐",
include: ['米饭', '菜'],
getName : function(){
alert(this.name)
}
}
//此时constructor 属性就不再指向Product了,变成了Object
/*
* 原型模式的缺点,对于共享的引用类型,一个修改就会导致所有实例的修改
* */
var product1 = new Product();
var product2 = new Product();
console.log(product1.include)
console.log(product2.include)
product1.include.push('饮料');
console.log(product1.include)
console.log(product2.include)
//4.组合使用构造函数模式和原型模式
function User(name,mobile){
this.name = name;
this.mobile = mobile;
this.address = ['add1','add2']
}
User.prototype = {
constructor: User,
getName: function(){
alert(this.name)
}
}
var user1 = new User('Jack','13312345678');
var user2 = new User('Tom','13011111111');
console.log(user1.address)
console.log(user2.address)
user1.address.push("add3")
console.log(user1.address)
console.log(user2.address)
//实例属性在构造函数中定义,而所有实例共享的属性和方法在原型中定义
</script>
继承
<script>
// 1.原型继承
function SuperType(){
this.prototype = true;
this.color = ['red','blue']
}
SuperType.prototype.getSuperValue = function(){
return this.prototype;
}
function SubType(){
this.subpropertype = false;
}
//继承
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function(){
return this.subpropertype;
}
var instance = new SubType();
alert(instance.getSuperValue());//true
//原型继承的问题 包含引用类型的原型
var instance1 = new SubType();
instance1.color.push("green");
console.log(instance1.color)
var instance2 = new SubType();
console.log(instance2.color)
//2.借用构造函数
//好处:可以传递参数
function SuperType(id,name){
this.color = ['red','blue'];
this.id = id;
this.name = name;
}
function SubType(){
//继承 SuperType
SuperType.call(this,'11','name')
}
var instance1 = new SubType();
instance1.color.push("green");
console.log(instance1.color)
var instance2 = new SubType();
console.log(instance2.color)
console.log(instance2.id)
console.log(instance2.name)
//call apply 实际上是在未来将要新创建的SubType实例环境下调用了SuperType构造函数。这样每个实例上就有自己的属性副本
//3.组合继承 原型链和借用构造函数组合
function SuperType(name){
this.color = ['red','blue'];
this.name = name;
}
SuperType.prototype.sayName = function(){
console.log(this.name)
}
function SubType(name,id){
//继承 SuperType 属性
SuperType.call(this,name);
this.id = id;
}
//继承方法
SubType.prototype = new SuperType();
SubType.prototype.sayId = function(){
console.log(this.id)
}
var instance1 = new SubType('instance1',1);
instance1.color.push("green");
console.log(instance1.color)
instance1.sayName();
instance1.sayId();
var instance2 = new SubType('instance2',2);
console.log(instance2.color)
instance2.sayName();
instance2.sayId();
</script>