面试必问之MVC

227 阅读3分钟

MVC: Model View Controller

如何解决代码写了就忘

写完的代码过了一周就忘记是干嘛的了。
那就是用使用MVC!

M :model 模块化

告诉程序,你的数据有哪些操作。

V :view 用户看得见的东西

顾名思义,view就是视图。告诉程序,你的代码在哪一块。

C :controller 控制器

controller 负责其他的所有代码。

MVC的操作就是:

js文件中:
!function(){ // 为什么用 !function(){}.call()
    var view = document.querySelector('html中view对应的部分') // 把html的view传到这里的view
    var model = { // 所有对数据的操作都放在model里
        init: function(){},
        fetch: function(){},
        save: function(){},
        ···: ···
    }
    var controller = {  // 创造一个controller对view进行操作
        view: null, // 先声明view
        xxxx: xxxx, // 其余的按照需求增加
        init: function(view){
            this.view = view // 1.请问这里的this是谁?
            this.bindEvents() 
            // this.bindEvents.call(this)
        },
        bindEvents: function(){
            window.addEventListener('onclick',function(){
              this.active // 2.请问这里的this是谁?  
            }.bind(this) 
        },
        active: function(){},
        ···: ···,
    }
    controller.init(view)
    // controller.init.call(controller,view)
}.call()

MVC描述:

  • MVC是一种组织形式,它不是任何一种框架,也不是任何一种技术,它就是一种组织代码的思想。

  • 它声明一个view,代表这个js文件操作的html是哪一部分。

  • model是包含所有关于数据的操作,比如获得数据,初始化数据等。

  • controller是一个对象,对象里有很多键值对,把重要的属性(比如view)和重要的操作(比如init、bindEvents)作为controller的属性写进去,这样我们对view的操作一目了然。

  • 对于单一的文件可能这样做看起来比直接写麻烦,但是对于多个JS文件,使用MVC结构是极大的优化。

    如图描述:
    controller监听view,当用户点击了view,controller就调用model,model向server发请求,server返回响应给model,model把数据返回给controller,controller更新view。

代码中提出了几个问题

  1. 为什么使用 !function(){}.call()
  2. 请问这里的this是谁?

如果你都知道答案,说明你对闭包、立即执行函数有了一定的了解。
如果你不知道,请继续往下看。

1. 为什么使用 !function(){}.call()

如何使用立即执行函数

  1. 我们不想要全局变量
  2. 我们要使用局部变量
  3. ES 5 里面,只有函数有局部变量
  4. 于是我们声明一个 function xxx,然后 xxx.call()
  5. 这个时候 xxx 是全局变量(全局函数)
  6. 所以我们不能给这个函数名字
  7. function(){}.call()
  8. 但是 Chrome 报错,语法错误
  9. 试出来一种方法可以不报错:
第一种方法
!function(){}.call() 
我们不在乎这个匿名函数的返回值,所以加个 ! 取反没关系  

第二种方法:
(function(){}).call()  
不推荐 
    如果有人手贱在这种方法的上一行写了个xxx,如下
         xxx    
         (function(){}).call() 
     
    这样浏览器就会认为是xxx(function(){}).call(),就会报错
     
 第三种方法:
xxxx12312542435423123.call() 
不推荐

所以就用第一种方法最好啦!

如何使用闭包

  1. 立即执行函数使得 person 无法被外部访问
  2. 闭包使得匿名函数可以操作 person
  3. window.frankGrowUp 保存了匿名函数的地址
  4. 任何地方都可以使用 window.frankGrowUp

=>
任何地方都可以使用 window.frankGrowUp 操作 person,但是不能直接访问 person

(此处有个例子)

2. 请问这里的this是谁?

代码中已经有所注释,还看不明白就使用.call(),把this写出来。 可以简单的理解,如果一个对象.call(),那么this就指向这个对象。