14-面向对象编程

工厂模式

  • 通过函数来创建对象,称为工厂模式
  • 工厂模式的缺点:创建对象没有特定类型
function createObj(id, name, val) {
    var o = new Object()
    o.id = id
    o.name = name
    o.val = val
    return o
}
o1 = createObj(1, 'first', 10)
o2 = createObj(2, 'second', 20)
#代码示例
function createUser(name, age, sex){
    var  o = new Object()
    o.name = name
    o.age  = age
    o.sex  = sex
    o.toString = function(){
        return "我的名字" + o.name + "我的年龄:"+o.age + "性别:" + o.sex
    }
    return o
}
wangsan = createUser("wangsan", 18, "girl")

构造函数模式

function Person(name, age, sex) {
    this.name = name
    this.age = age
    this.sex = sex
}

wangSan = new Person('wang san', 18, 'man')
cuihua = new Person('cuihua', 20, 'woman')
//通过构造函数模式,可以创建自己的类型
//构造函数是通过new关键字创建函数实例对象
//代码示例:
function Person(name, age, sex) {
    this.name = name
    this.age  = age
    this.sex  = sex
    this.getName = function(){
        console.log(this.name)
    }
}
// o = Person("wanger", 18, "girl")
wanger   = new Person("wanger", 18, "girl")
zhangsan = new Person("zhangsan", 28, "boy")

//可以通过实例的constructor属性查看自己的构造函数
console.log(wanger.constructor)
console.log(wanger instanceof Person)

/* 
构造函数的缺点:
 构造函数方式主要是造成每个实例都会定义自己的方法,这样会占用更多的内存
 */
// console.log(wanger.getName)
// console.log(zhangsan.getName)

/* 
 两个实例相同的方法并不是同一个对象
 */
console.log(wanger.getName == zhangsan.getName)

 

原型模式

  • 实例之间不能共享方法
  • 函数对象原型Person.prototype
function Person(){
    
}
Person.prototype = {
    hello:function(){
        console.log("hello")
        console.log(this.name)
    }
}
person_1 = new Person()
person_2 = new Person()

person_1.name = "luxp"
person_2.name = "lisi"

person_1.hello()
person_2.hello()

function Person(name, age, sex) {
    this.name = name
    this.age  = age
    this.sex  = sex
    this.family = []
    this.say = function(){
        console.log("my name is "+this.name)
    }
}

wanger   = new Person("wanger", 18, "girl")
zhangsan = new Person("zhangsan", 28, "boy")

// 在原型上添加一个方法{}

Person.prototype.getName = function(){
    console.log(this.name)
}


console.log(wanger.say == zhangsan.say)
//还可以增加共同的属性 - 相当于python的类属性

Person.prototype.hands = 2
console.log(wanger.hands)

Person.prototype.getSex = function(){
    console.log(this.sex)
}

console.log(wanger.getSex())

//
//这样设定,等于重写了prototype

Person.prototype = {
    "getAge":function (){
        console.log(this.age)
    }
}

lisi = new Person("lisi", 38, "boy")

apply与call

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <script type="text/javascript">
            /*
            call是函数对象的一个方法
            通过call可以指定函数内部的this对象
            第一个参数是this指向的对象,后面通过逗号分隔传递多个参数
            例如:Function.call(obj,args1,args2,args3...)
            */
            function myFun(property){
                console.log(this)
                console.log(this.name)
                console.log(this[property])
                
            }
            var o1 = {
                name:"luxp",
                sex:""
            }
            var o2 = {
                name:"whh",
                sex:""
            }
            myFun.call(o2,"name")
            myFun.call(o2,"sex")
            
            /*apply也是是函数对象的一个方法
            功能与call一样,不同的是参数传递方式
            第一个参数是this指向的对象,第二个是参数数组
            例如:Function.apply(obj, [args1,arg2,…])
            */
            myFun.apply(o1, ["sex"])
            myFun.apply(o2, ["sex"])
           
        </script>
    </body>
</html>

原型继承

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <script type="text/javascript">
            // 父类构造函数
            function Person(name, age, sex) {
                this.hands = 2
                this.legs  = 2
                this.family  = []
                this.say = function(){
                    console.log("my name is "+this.name)
                }
            }
            
            //子对象结构函数
            function Man(name, age){
                this.name = name
                this.age  = age
                this.sex = ""
                
            }
            
            //将原型指向到Person,即可继承
            Man.prototype = new Person()
            
            //重写原型方法
            Man.prototype.say = function(){
                    console.log("welcome to here")
                }
            
            // 
            wangwu = new Man("wangwu", 58)
            zhangsan = new Man("zhangsan", 28)
            
            
            function WoMan(name, age){
                this.name = name
                this.age  = age
                this.sex  = ""
            }
            
            //将原型指向到Person
            WoMan.prototype = new Person()
            //重写原型方法
            WoMan.prototype.say = function(){
                console.log("hi,what can i do for you?")
            }
            
            cuihua = new WoMan("cuihua", 18)
            
            // 添加家庭成员
            wangwu.family.push("whife")
            
            // 尴尬的事情,同一个Man的对象,引用型属性是相互共享的
            lisi = new Man("lisi", 28)
            lisi.family.push("son")
            // console.log(lisi.family)

        </script>
    </body>
</html>

原型继承改进方式

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <script type="text/javascript">
            // 改进引用类型值在各个实例共享的问题
            function Person(name,age,sex,family) {
                this.hands = 2
                this.legs  = 2
                this.family  = family
                this.say = function(){
                    console.log("my name is "+this.family)
                }
            }
            
            //将原型指向到Person,即可继承
            Man.prototype = new Person()
            
            //子对象结构函数
            function Man(name,age,sex){
                console.log(Man.prototype)
                console.log(Man.prototype.constructor)
                // 相当于python的super()执行
                // 等价于Person.call
                Man.prototype.constructor.call(this,name,age,sex,[])
            }
            
            wangwu = new Man("wangwu", 58)
            wangwu.family.push("father")
            lisi = new Man("lisi", 28)
            lisi.family.push("wife")
            // console.log(lisi.family)</script>
    </body>
</html>
  •  定义一个车的构造函数,然后再定义汽车,自行车的构造函数,汽车与自行车主要是动力不同,轮子数量不一样
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <script type="text/javascript">
            // 定义一个车的构造函数,然后再定义汽车,自行车的构造函数,汽车与自行车主要是动力不同,轮子数量不一样
            function Vehicle(){
                
            }
            Vehicle.prototype.move = function(){
                console.log("move speed",this.speed)
                
            }
            function Car(power){
                Car.prototype.constructor.call(this)
                this.wheel = 4
                this.speed = 100
            }
            Car.prototype = new Vehicle()
            function Bike(power){
                Bike.prototype.constructor.call(this)
                this.wheel = 2
                this.speed = 40
            }
            Bike.prototype = new Vehicle()
            var car = new Car()
            var bicycle = new Bike()
            
        </script>
    </body>
</html>

 

posted @ 2021-05-21 20:05  西瓜的春天  阅读(60)  评论(0)    收藏  举报