美文网首页
面向对象编程初探

面向对象编程初探

作者: lyp82nkl | 来源:发表于2019-06-26 00:03 被阅读0次

面向对象程序设计:Object-oriented programming(OOP)

逻辑运算符的知识:

且(&&)运算符

五个falsy 值:(‘’,0,NaN,null,undefined)

&& 运算符返回第一个 falsy 值(停止运算),若无 falsy 值,则返回最后一个 truthy 值

1&&0&&2&&3
//0  也就是这里面的第一个falsy值
console.log(3) && 0
//undfined  并且console.log(3)执行了,因为console.log()的值是undefined,是一个falsy值,所以就返回undefined
0&&console.log(3)
//0  第一个falsy值是0,然后直接返回0,console.log(3)不会执行

或(||)运算符

  1. 如果运算表达式里的值里有除falsy值以外的值
    那么就返回第一个真值
    如:
0||1||null
//1  因为1不是falsy值
  1. 如果运算表达式里的值全是falsy值,那么返回最后一个falsy值
    如:
0||''||null
//null

|| 运算符返回第一个 truthy 值(停止运算),若无 truthy 值,则返回最后一个 falsy 值

使用全局变量时给一个变量赋值要注意的问题

var app = {}
//危险代码 如果之前有人声明了一个全局app变量,你这样直接写会覆盖之前的

正确写法:

var app = app || {}
 
//就相当于
If(app){
  app = app
}else{
  app = {}
}

上面的代码的意思是如果全局变量app这个变量存在,那么全局变量app就等于之前存在的那个变量app,否则app就等于一个空对象

命名空间

var app = app || {}

就是全局命名空间

之后所有的方法和属性都可以写在app上面,app就像一个房间一样装这所有的属性和方法,所以叫做命名空间

比如:

app.event= {}
app.commonMethod = {
  Name: ‘’,
  Age: ‘’
}
app.init= function(){}

另外我们的文件夹也相当于一个命名空间

构造函数:constructor(类:class)

JavaScript 基于原型,没有类的概念;但是我们可以定义一个类
下面代码就是一个新的类 Person

function Person() { } 
// 或
var Person = function(){ }

JavaScript 中类的本质是函数,只是它有两个特点:
1.函数体内部使用了this关键字,代表了所要生成的对象实例。
2.生成对象的时候,必须使用new命令
这两个特点就形成了所谓的构造函数
为了与普通函数区别,构造函数名字的第一个字母通常大写,如这里的Person

对象(类的实例)

function Person() { }
var person1 = new Person();
var person2 = new Person();

以 Person 为类(模版),person1 和 person2 是 Person 新的实例:person1、person2 可以调用函数 Person

为什么会有面向对象编程?

写了一个 person1 ,又写了一个 person2 ,然后又写了一个 person3 。。。
它们有很多重复的代码:这些代码结构一致(如我们之前的 MVC 设计模式,简直浪费内存(内存条那么贵)
于是就有了 Person 这个构造函数作为对象的模板:把所有相同结构的代码用一个函数封装起来
可以让 person1 等只需要用 new 的方法调用这个 Person 传入参数来使用它的模版,person1 自身属性,再单独罗列即可
原来代码

! function () {
    // MVC 的 V
    var view = document.querySelector('section.message')
    //添加 M
    var model = {
        init: function () {
            var APP_ID = '2zeITbbU6cgHT0mdBscQtmp0-gzGzoHsz'
            var APP_KEY = 'iByF5Dy55tJodAoxC4cxwAwx'

            AV.init({
                appId: APP_ID,
                appKey: APP_KEY
            })
        },
        //获取所有数据
        fetch: function () {
            var query = new AV.Query('Message')
            return query.find() //Promise 对象
        },
        //创建数据
        save: function (name,content) {
            var Message = AV.Object.extend('Message');
            var message = new Message();
            return message.save({ //Promise 对象
                name: name,
                content: content
            })
        }
    }
    // MVC 的 C
    var controller = {
        view: null,
        model: null,
        messageList: null,
        init: function (view, model) {
            this.view = view
            this.model = model
            this.messageList = view.querySelector('#messageList')
            this.form = view.querySelector('form')
            this.model.init()
            this.loadMessages()
            this.bindEvents()
        },
        loadMessages: function () {
            this.model.fetch().then((messages) => {
                let array = messages.map((item) => item.attributes)
                array.forEach((item) => {
                    let li = document.createElement('li')
                    li.innerText = `${item.name} : ${item.content}`
                    this.messageList.appendChild(li)
                })
            })
        },
        bindEvents: function () {
            this.form.addEventListener('submit', (e) => {
                e.preventDefault()
                this.saveMessage()
            })
        },
        saveMessage: function () {
            let myForm = this.form
            let content = myForm.querySelector('input[name=content]').value
            let name = myForm.querySelector('input[name=name]').value
            this.model.save(name, content).then(function (object) {
                let li = document.createElement('li')
                li.innerText = `${object.attributes.name} : ${object.attributes.content}`
                let messageList = document.querySelector('#messageList')
                messageList.appendChild(li)
                myForm.querySelector('input[name=content]').value = ''
                console.log(object)
            })
        }
    }
    controller.init(view, model)
}.call()
把 M、V、C 三个模版单独分出

M 的模版

// Model 办事,我放心
// 通过全局函数 window 引入 Model 便于所有 model 调用
// 提供三个参数:Options、resourceName 和 object
window.Model = function (Options) {
    let resourceName = Options.resourceName
    return {
        init: function () {
            var APP_ID = '2zeITbbU6cgHT0mdBscQtmp0-gzGzoHsz'
            var APP_KEY = 'iByF5Dy55tJodAoxC4cxwAwx'

            AV.init({
                appId: APP_ID,
                appKey: APP_KEY
            })
        },
        fetch: function () {
            var query = new AV.Query(resourceName)
            return query.find()
        },
        //创建数据
        save: function (object) {
            var X = AV.Object.extend(resourceName)
            var x = new X();
            return x.save(object)
        }
    }
}

V 就比较简单了,就一句话,但是封装后也可以调用以便减少代码

window.View = function(Selector){
    return document.querySelector(Selector)
}

这里 C 是有一定难的,需要对 this 的概念有所理解

window.Controller = function (options) {
    var init = options.init //这个 init 就是 controller 传进来的,记为 initB
    // 4-21 return 一个 object
    let object = {
        view: null,
        model: null,
        init: function (view, model) { // 注意这里的 init 是 object 的属性,记为 initA
            this.view = view
            this.model = model
            this.model.init()
            // 3.initB.call(this)
            init.call(this, view, model) // 这里的 init 当然是 initB,写成这样 init(view,model) 你就懂了
            this.bindEvents.call(this)
        },
    }
    // 把除 init 外的所有 options 的参数传给 object
    // init 是公共参数,而其他实例独有的参数需要传进来
    for (let key in options) {
        if (key !== 'init') {
            object[key] = options[key]
        }
    }
    return object
}

现在可以直接调用 M、V、C 了,其他实例也是一样的

! function () {
    // MVC 的 V
    // 这里 window.View 的 window 可以省略,是默认的
    var view = View('section.message')
    //添加 M
    var model = Model({
        resourceName: 'Message'
    })
    // MVC 的 C
    // 1.controller === object
    var controller = Controller({
        init: function () {
            this.messageList = view.querySelector('#messageList')
            this.form = view.querySelector('form')
            this.loadMessages()
            // 这里的 this 是 object,但是 object 没有上面参数
            // 所以才要 for...in...遍历一下,让 object 有这些 controller 独有的参数
        },
        loadMessages: function () {
            this.model.fetch().then((messages) => {
                let array = messages.map((item) => item.attributes)
                array.forEach((item) => {
                    let li = document.createElement('li')
                    li.innerText = `${item.name} : ${item.content}`
                    this.messageList.appendChild(li)
                })
            })
        },
        bindEvents: function () {
            this.form.addEventListener('submit', (e) => {
                e.preventDefault()
                this.saveMessage()
            })
        },
        saveMessage: function () {
            let myForm = this.form
            let content = myForm.querySelector('input[name=content]').value
            let name = myForm.querySelector('input[name=name]').value
            this.model.save({
                name: name,
                content: content
            }).then(function (object) {
                let li = document.createElement('li')
                li.innerText = `${object.attributes.name} : ${object.attributes.content}`
                let messageList = document.querySelector('#messageList')
                messageList.appendChild(li)
                myForm.querySelector('input[name=content]').value = ''
                console.log(object)
            })
        }
    })
    // 2.controller.init(view, model)
    controller.init(view, model)
}.call()

关于 this

1.controller === object
2.controller.init(view, model)
  写成 call 的形式:controller.init.call(controller, view, model)
 // MDN 里 this 文档告诉我们:this 是 call 的第一个参数
  显然 controller.init 里面的 this 当然是 controller
  那它还是 object:即 controller.init 里面的 this 就是 object
  相当于 object.init 里面的 this 是 object
3.initB.call(this)
  initB 里面的 this === call 后面的this
  call 后面 this === 第二条里的 this
  第二条里面的 this === object
  => initB 里面的 this 就是 object

相关文章

  • 10 Go面向“对象”:面向接口编程

    一、面向对象初探 在软件开发领域,你应该听到过过程式编程、面向对象编程、甚至函数式编程等软件开发方式。而面向对象编...

  • 面向对象编程初探

    面向对象程序设计:Object-oriented programming(OOP) 逻辑运算符的知识: 且(&&)...

  • 面向对象_初识

    目录 面向对象编程介绍 类与对象介绍 私有属性与私有方法 面向对象编程 1. 面向对象编程介绍 面向对象编程:Ob...

  • 谈谈面向对象编程

    何为面向对象编程 面向对象编程简介 面向对象编程(Object-oriented Programming,缩写:O...

  • 面向对象基础

    面向对象编程包括: 面向对象的分析(OOA) 面向对象的设计(OOD) 面向对象的编程实现(OOP) 面向对象思想...

  • python-day14

    一、面向对象编程 编程思想:1.面向对象编程 --> 算法,逻辑2.函数式编程 --> 函数3.面向对象编程 ...

  • PHP全栈学习笔记8

    面向对象的基本概念,面向对象编程,oop,面向对象,面向对象的分析,面向对象的设计,面向对象的编程,什么是类。 类...

  • PHP全栈学习笔记8

    面向对象的基本概念,面向对象编程,oop,面向对象,面向对象的分析,面向对象的设计,面向对象的编程,什么是类。 类...

  • 面向对象浅析

    ### 面向对象编程和面向对象编程语言 面向对象编程的英文缩写是 OOP,全称是 Object Oriented ...

  • 2017-08-14

    面向对象编程用对象的思想去写代码,就是面向对象编程-面向过程-面向对象面向对象编程的特点1.抽象 抽取一样的东西...

网友评论

      本文标题:面向对象编程初探

      本文链接:https://www.haomeiwen.com/subject/cvmfcctx.html