zoukankan      html  css  js  c++  java
  • ♫【面向对象】

    var Car = function() {
        this.init()
    }
    Car.prototype.init = function() {
        console.log(this)
    }
    function Person() {
        this.init()
    }
    Person.prototype.init = function() {
        console.log(this)
    }
    var car = new Car
    var person = new Person
    console.log(car.constructor) // function(){}
    console.log(person.constructor) // function Person() {}

    面向对象的 Javascript (声明篇)
    http://www.gracecode.com/posts/934.html
    面向对象的 Javascript (继承篇)
    http://www.gracecode.com/posts/969.html

    /**
     * 工厂模式 
     */
    ;(function() {
        function showColor() {
            console.log(this.color)
        }
    
        function createCar(sColor) {
            var oCar = new Object
            oCar.color = sColor || 'red'
            oCar.showColor = showColor
    
            return oCar
        }
    
        var oCar = createCar()
        oCar.showColor()
    })()
    
    /**
     * 构造函数模式
     * 构造函数返回的就是其this的值,所以不必使用return返回
     */
    ;(function() {
        function showColor() {
            console.log(this.color)
        }
    
        function Car(sColor) {
            this.color = sColor
            this.showColor = showColor
        }
    
        var oCar = new Car('red')
        oCar.showColor()
    })()
    
    /**
     * 混合模式 
     */
    ;(function() {
        function Car(sColor) {
            this.color = sColor
        }
    
        Car.prototype.showColor = function() {
            console.log(this.color)
        }
    
        var oCar = new Car('red')
        oCar.showColor()
    })()
    
    /**
     * 动态原型模式
     */
    ;(function() {
        function Car() {
            this.color = 'red'
            if (typeof Car._initialized === 'undefined') {
                Car.prototype.showColor = function() {
                    console.log(this.color)
                }
                Car._initialized = true
            }
        }
    
        var oCar = new Car('red')
        oCar.showColor()
    })()
    
    /**
     * 混合工厂模式
     */
    ;(function() {
        function Car() {
            var oCar = {}
            oCar.color = 'red'
            oCar.showColor = function() {
                console.log(this.color)
            }
    
            return oCar
        }
    
        var oCar = new Car()
        oCar.showColor()
    })() 
    
    /**
     * 通常使用的是 混合模式 与 动态原型模式
     * 不过不要单独使用 工厂模式 与 构造模式 (或者其两者的结合体),因为这样会造成不必要的浪费
     /

    Javascript 面向对象编程(一):封装
    http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_encapsulation.html
    Javascript面向对象编程(二):构造函数的继承
    http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html
    Javascript面向对象编程(三):非构造函数的继承
    http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance_continued.html

    封装

    /**
     * 对于每一个实例对象,type属性和eat()方法都是一模一样的内容,每一次生成一个实例,都必须为重复的内容,多占用一些内存
     */
    ;(function() {
        function Cat(name, color) {
            this.name = name
            this.color = color
            this.type = '猫科动物'
            this.eat = function() {
                console.log("吃老鼠")
            }
        }
        var cat1 = new Cat('大毛', '黄色')
        var cat2 = new Cat('大毛', '黄色')
        console.log(cat1.eat == cat2.eat)
    })()
    
    /* 
     * Javascript规定,每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承
     * 这意味着,我们可以把那些不变的属性和方法,直接定义在prototype对象上
     * 这时所有实例的type属性和eat()方法,其实都是同一个内存地址,指向prototype对象,因此就提高了运行效率
     */
    ;(function() {
        function Cat(name, color) {
            this.name = name
            this.color = color
        }
        Cat.prototype.type = '猫科动物'
        Cat.prototype.eat = function() {
            console.log("吃老鼠")
        }
        var cat1 = new Cat('大毛', '黄色')
        var cat2 = new Cat('大毛', '黄色')
        console.log(cat1.eat == cat2.eat)
    })()
    function Cat(name, color) {
        this.name = name
        this.color = color
    }
    
    var cat1 = new Cat('大毛', '黄色')
    console.log(cat1.name)
    
    /**
     * constructor
     * cat1会自动含有一个constructor属性,指向它们的构造函数
     */
    console.log(cat1.constructor === Cat)
    
    /**
     * instanceof
     * 验证原型对象与实例对象之间的关系
     */
    console.log(cat1 instanceof Cat)
    
    Cat.prototype.type = '猫科动物'
    Cat.prototype.eat = function() {
        console.log('吃老鼠')
    }
    
    /**
     * isPrototypeOf
     * 这个方法用来判断,某个proptotype对象和某个实例之间的关系
     */
    console.log(Cat.prototype.isPrototypeOf(cat1))
    
    /**
     * hasOwnProperty
     * 判断某一个属性到底是本地属性,还是继承自prototype对象的属性
     */
    console.log(cat1.hasOwnProperty('type'), cat1.hasOwnProperty('name')) 
    
    /**
     * in
     * in运算符可以用来判断,某个实例是否含有某个属性,不管是不是本地属性
     */
    console.log('name' in cat1)
    for (var prop in cat1) {
        console.log('cat1[' + prop + ']=' + cat1[prop])
    }

    构造函数的继承

    function Animal() {
        this.species = '动物'
    }
    Animal.prototype.food = '食物' // 不变的属性都可以直接写入Animal.prototype
    /**
     * 构造函数绑定
     */
    function Cat(name, color) {
        Animal.apply(this, arguments)
        this.name = name
        this.color = color
    }
    var cat1 = new Cat('大毛', '黄色')
    console.log(cat1.species)
    
    /**
     * prototype模式
     */
    function Dog(name, color) {
        this.name = name
        this.color = color
    }
    Dog.prototype = new Animal()
    console.log(Dog.prototype.constructor == Animal)
    Dog.prototype.constructor = Dog
    var dog1 = new Dog('大毛', '黄色')
    console.log(dog1.constructor == Dog.prototype.constructor)
    console.log(dog1.constructor == Dog)
    console.log(dog1.species)
    
    /**
     * 利用空对象作为中介
     * Parent.prototype only
     * Child.uber 意思是为子对象设一个uber属性,这个属性直接指向父对象的prototype属性。(uber是一个德语词,意思是"向上"、"上一层"。)
     * 这等于在子对象上打开一条通道,可以直接调用父对象的方法。这一行放在这里,只是为了实现继承的完备性,纯属备用性质
     */
    function Fish(name, color) {
        this.name = name
        this.color = color
    }
    function extend(Child, Parent) {
        var F = function() {}
        F.prototype = Parent.prototype
        Child.prototype = new F()
        Child.prototype.constructor = Child
        Child.uber = Parent.prototype
    }
    extend(Fish, Animal)
    var fish1 = new Fish('大毛', '黄色')
    console.log(fish1.food)
    
    /**
     * 拷贝继承
     */
    function People(name, color) {
        this.name = name
        this.color = color
    }
    function extend2(Child, Parent) {
        var p = Parent.prototype
        var c = Child.prototype
        for (var i in p) {
            c[i] = p[i]
        }
        c.uber = p
    }
    extend2(People, Animal)
    var people1 = new People('大毛', '黄色')
    console.log(people1.food)

    非构造函数的继承

    /**
     * object()方法
     */
    var Chinese = {
        nation: '中国', // string
        city: ['杭州', '上海'], // object
        eat: function() { // function
            console.log('食物')
        }
    } 
    function object(o) {
        function F() {}
        F.prototype = o
        return new F()
    }
    var Doctor = object(Chinese)
    Doctor.career = '医生'
    console.log(Doctor.nation)
    
    /**
     * 浅拷贝
     * 基本类型的数据
     */
    
    /**
     * 深拷贝
     * 基本类型的数据
     */
    function deepCopy(p, c) {
        var c = c || {}
        for (var i in p) {
            console.log(typeof p[i])
            if (typeof p[i] === 'object') {
                c[i] = (p[i].constructor === Array) ? [] : {}
                deepCopy(p[i], c[i])
            } else {
                c[i] = p[i]
            }
        }
        return c
    }
    Chinese.birthPlaces = ['北京','上海','香港']
    var Teacher = deepCopy(Chinese)
    Teacher.birthPlaces.push('厦门')
    console.log(Chinese.birthPlaces)
    console.log(Teacher.birthPlaces)
  • 相关阅读:
    == 和equals方法
    ObjectInputStream 与ObjectOutputStream
    IOS基础:ObjectiveC 数组处理
    学习笔记:自定义方法的两种实现方式
    DatePicker 获取时间的时区问题
    IOS基础:tableview中cell
    IOS基础:窗口切换的几种方法
    IOS基础:ObjectiveC 字符串处理
    使用 Notifications
    学习笔记:Tab Bar 控件使用详解
  • 原文地址:https://www.cnblogs.com/jzm17173/p/3035727.html
Copyright © 2011-2022 走看看