JavaScript MVC设计模式(构造器、模块和原型)教程

JavaScript面向对象

JavaScript是一种无类语言,但可以使用函数来模拟,这就涉及到设计模式。模式是一种已经验证过的可复用的解决方案,可用于解决软件设计中遇到的常见的问题,通常将这些解决方案制作成模板来复用。

而JavaScript模拟类常用的方式是定义一个JavaScript函数,使用this来定义属性和方法,然后使用new关键字创建对象实例。如

 代码如下 复制代码

    function webSite(){
    this.name="开源视窗";
    this.url="oseye.net";
    this.getInfo=function(){
    return this.name+" : "+this.url;   
    }
    }
    
    var wb=new webSite();
    console.log(wb.getInfo());

创建对象

在JavaScript中,创建新对象的两种常用方法如:

 代码如下 复制代码

    var newObject={};
    var newObject=new Object();

然而这两种方式只是创建一个空对象,没有任何用处,但有一下四种方式可以扩展它:

 代码如下 复制代码

    var webSite={};
    //"点"语法
    webSite.url="oseye.net";
    webSite.getInfo=function(){
    return this.url;
    }
    console.log(webSite.getInfo());
    console.log(webSite.url);
    
    //中括号语法
    webSite["name"]="开源视窗";
    console.log(webSite.name);
    console.log(webSite["name"]);
    
    //用Object.defineProperty
    Object.defineProperty(webSite,"url",{
    value:"oseye.net by defineProperty",
    writable:true,
    enumerable:true,
    configurable:true
    });
    console.log(webSite.url);
    
    //使用Object.defineProperties
    Object.defineProperties(webSite,{
    "url":{
    value:"oseye.net by defineProperties",
    writable:true,
    enumerable:true,
    configurable:true
    },
    "name":{
    value:"开源视窗 by defineProperties",
    writable:true
    }   
    });
    console.log(webSite.url + webSite.name);

而使用Object.create可以实现继承,如:

    var webSite={};
    webSite.url="oseye.net";
    //创建myWebSite继承自webSite
    var myWebSite=Object.create(webSite);
    console.log(myWebSite.url);

Constructor(构造器)模式

在经典面向对象编程语言中,构造器是一种在内存已经分配给对象的情况下,用于初始化新创建对象的特殊方法。虽然JavaScript不支持类的概念,但它确实支持与对象一起用的特殊构造器函数,如:

 代码如下 复制代码

    function webSite(name,url){
    this.url=url;
    this.name=name;
    this.getInfo=function(){
    return this.url+" - "+this.name;   
    }
    }
    
    var ws=new webSite("开源视窗","oseye.net");
    console.log(ws.getInfo());

Module(模块)模式

模块模式是基于对象字面量的,因此需要认识对象字面量的含义。在对象字面量表示法中,一个对象被描述为一组包含大括号({})中、以逗号分隔的name/value对,而谨记对象的最后一个name/value后面不需要逗号,否则语法错误。语法如下:

 代码如下 复制代码

    var newObject={
    variableKey:variableValue,
    fucntionKey:function(){
    //.....
    }
    };

示例:

 代码如下 复制代码

    var webSite={
    url:"oseye.net",
    getInfo:function(){
    return this.url;
    }   
    };
    console.log(webSite.getInfo());

Prototype(原型)模式

每个JavaScript对象都有一个prototype属性,使用使用prototype属性,可以给类动态地添加方法,以便在JavaScript中实现“继承”的效果。其实prototype属性是指向一个对象的引用,这个对象称为原型对象,原型对象包含函数实例共享的方法和属性,也就是说将函数用作构造函数调用(使用new操作符调用)的时候,新创建的对象会从原型对象上继承属性和方法。

看到上面的描述,新手一定云里雾里的!在理解prototype之前我们来看几个面向对象中常见的东东:

    私有变量、函数:在函数内定义的变量和函数如果不对外提供接口,那么外部将无法访问到,也就是变为私有变量和私有函数

 代码如下 复制代码

        function webSite(){
        url="oseye.net";
        var getInfo=function(){
        }
        };
        //在webSite对象外部无法访问变量url和函数getInfo,它们就变成私有的,只能在webSite内部使用.
        //即使是函数webSite的实例仍然无法访问这些变量和函数,异常提示“undefined”
        console.log(new webSite().getInfo());

    静态变量、函数:当定义一个函数后通过 “.”为其添加的属性和函数,通过对象本身仍然可以访问得到,但是其实例却访问不到,这样的变量和函数分别被称为静态变量和静态函数,用过Java、C#的同学很好理解静态的含义。

 代码如下 复制代码

        function webSite(){};
        webSite.url="oseye.net";
        
        console.log(webSite().url); //oseye.net
        console.log(new webSite().url); //undefined

    实例变量、函数:在面向对象编程中除了一些库函数我们还是希望在对象定义的时候同时定义一些属性和方法,实例化后可以访问,JavaScript是通过this做到的

 代码如下 复制代码

        function webSite(){
        this.url="oseye.net";
        this.getInfo=function(){
        return this.url;   
        }   
        };
        
        console.log(new webSite().url); //oseye.net
        console.log(new webSite().getInfo()); //oseye.net

    看着还不错,但你再看

 代码如下 复制代码

        function webSite(){
        this.url="oseye.net";
        this.getInfo=function(){
        return this.url;   
        }   
        };
        
        var ws=new webSite();
        ws.url="test.oseye.net";
        ws.getInfo=function(){
        return "override getInfo";   
        }
        
        console.log(ws.url); //test.oseye.net
        console.log(ws.getInfo()); //override getInfo
        
        var ws2=new webSite();
        console.log(ws2.url); //oseye.net
        console.log(ws2.getInfo()); //oseye.net

由此可以得出一个结论:每个实例的属性和方法都是对象属性和方法的一个复制。如果一个对象有成千上万个实力方法,那么每个实例都要这么一个复制,有点小恐怖!!这时prototype应运而生,

无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,默认情况下prototype属性会默认获得一个constructor(构造函数)属性,这个属性是一个指向prototype属性所在函数的指针,有些绕了啊,写代码、上图!

 代码如下 复制代码
    function Person(){}

根据上图可以看出Person对象会自动获得prototyp属性,而prototype也是一个对象,会自动获得一个constructor属性,该属性正是指向Person对象。

当调用构造函数创建一个实例的时候,实例内部将包含一个内部指针(很多浏览器这个指针名字为__proto__)指向构造函数的prototype,这个连接存在于实例和构造函数的prototype之间,而不是实例与构造函数之间。

 代码如下 复制代码

    function Person(name){
    this.name=name;
    }
    Person.prototype.printName=function(){
    alert(this.name);
    }
    
    var person1=new Person('Byron');
    var person2=new Person('Frank');

Person的实例person1中包含了name属性,同时自动生成一个__proto__属性,该属性指向Person的prototype,可以访问到prototype内定义的printName方法,大概就是这个样子的

 

写段程序测试一下看看prototype内属性、方法是能够共享

 代码如下 复制代码

    function Person(name){
    this.name=name;
    }
    
    Person.prototype.share=[];
    
    Person.prototype.printName=function(){
    alert(this.name);
    }
    
    var person1=new Person('Byron');
    var person2=new Person('Frank');
    
    person1.share.push(1);
    person2.share.push(2);
    console.log(person2.share); //[1,2]

果不其然!实际上当代码读取某个对象的某个属性的时候,都会执行一遍搜索,目标是具有给定名字的属性,搜索首先从对象实例开始,如果在实例中找到该属性则返回,如果没有则查找prototype,如果还是没有找到则继续递归prototype的prototype对象,直到找到为止,如果递归到object仍然没有则返回错误。同样道理如果在实例中定义如prototype同名的属性或函数,则会覆盖prototype的属性或函数。

当然prototype不是专门为解决上面问题而定义的,但是却解决了上面问题。了解了这些知识就可以构建一个科学些的、复用率高的对象,如果希望实例对象的属性或函数则定义到prototype中,如果希望每个实例单独拥有的属性或方法则定义到this中,可以通过构造函数传递实例化参数。

 

时间: 2024-09-23 13:42:47

JavaScript MVC设计模式(构造器、模块和原型)教程的相关文章

JavaScript 单体设计模式教程

一:什么是单体模式: 是什么:将代码组织为一个逻辑单元,这个单元中的代码通过单一的变量进行访问.只要单体对象存在一份实例,就可以确信自己的所有代码使用的是同样的全局资源. 用途:1.用来划分命名空间,减少网页中全局变量的数目. 2.在分支技术中用来封装浏览器之间的差异. 3.单体对象创建的命名空间可以快速清除全局变量. 4.增强模块性 关于单体模式的好坏,等你看完所有的讲解之后再告诉你哦....... 二:单体结构: 1.最简单的单体就是一个对象字面量. var ProductTools={  

超级简单实现JavaScript MVC 样式框架

 本文给大家分享的是一则翻译过来的,由国外友人写的如何简单有效的实现javascript MVC样式框架,算是一个MVC的入门教程,希望大家能够喜欢.     介绍 使用过JavaScript框架(如AngularJS, Backbone 或者Ember)的人都很熟悉在UI(用户界面,前端)中mvc的工作机理.这些框架实现了MVC,使得在一个单页面中实现根据需要变化视图时更加轻松,而模型-视图-控制器(mvc)的核心概念就是:处理传入请求的控制器.显示信息的视图.表示业务规则和数据访问的模型.

ASP.NET下MVC设计模式的实现

asp.net|设计 ASP.NET是微软最新推出的新型体系结构.NET框架的一部分,它为构造新一代动态网站和基于网络的分布式应用提供了强有力的支持.与以前的 Web 开发模型相比,ASP.NET 提供了许多重要的优点例如: 简易性:安全性:可管理性等.而且与基于过程的ASP页面技术相比,面向对象技术在ASP.NET中得到了完全实现.用传统ASP技术建立的Web应用实例中,在页面中同时实现显示,业务逻辑和流程控制,这从工程化的角度考虑,它有许多不足之处.用户界面承担着向用户显示问题模型和与用户进

超级简单实现JavaScript MVC 样式框架_javascript技巧

介绍 使用过JavaScript框架(如AngularJS, Backbone 或者Ember)的人都很熟悉在UI(用户界面,前端)中mvc的工作机理.这些框架实现了MVC,使得在一个单页面中实现根据需要变化视图时更加轻松,而模型-视图-控制器(mvc)的核心概念就是:处理传入请求的控制器.显示信息的视图.表示业务规则和数据访问的模型. 因此,当需要创建这样一个需要在单个页面中实现切换出不同内容的应用时,我们通常选择使用上述框架之一.但是,如果我们仅仅需要一个在一个url中实现视图切换的框架,而

Javascript oop设计模式 面向对象编程简单实例介绍_javascript技巧

Javascript oop设计模式 面向对象编程 最初我们写js代码的时候是这么写 function checkName(){ //验证姓名 } function checkEmail(){ //验证邮箱 } function checkPassword(){ //验证密码 } 这种方式会造成全局变量的严重污染,再过渡到 var checkObject = { checkName : function(){}; checkEmail: function(){}; checkPassword:

JavaScript实现设计模式中的单例模式的一些技巧总结_javascript技巧

一.使用全局变量保存单例 这是最简单的实现方法 function Person(){ this.createTime=new Date(); } var instance=new Person(); function getInstance(){ return instance; } 加载该js时就创建一个Person对象,保存到instance全局变量中,每次使用都取这个对象.如果一次都没使用,那么创建的这个对象则浪费了,我们可以优化一下, var instance function getI

ASP.NET的MVC设计模式

当开发者听到"设计模式"这个词时,他们通常联想到两个场景. 一组开发者正在讨论许多创造性意见,正在开会,但是却没有进行编码.另外一 组人能制定出正确的计划,保证系统能够开发成功,代码可以重用. 而现实一般都处于两者中间.在为他们的公司设计解决方案的时候,结构设计 者和系统设计者应该寻找重复的模式.但是模式只是开发健壮.可重用代码的一 个指导.结构设计者不能过多的去设计一个解决方案的结构,因为要定期交货. 过多的设计系统结构的主要受害者是Web应用程序.因为多数Web应用程序是用 来浏览

AngularJs:Javascript MVC框架

在6月google发布了AngularJs 1.0稳定版, 并宣称:AngularJS可以让你扩展HTML的语法,以便清晰.简洁地表示应用程序中的组件,并允许将标准的HTML作为你的模板语言,AngularJS可以通过双向数据绑定自动从拥有JavaScript对 象(模型)的UI(视图)中同步数据. 开始接触AngularJs是在4月份来到新项目组,这时AngularJs还处于0.8未稳定版,项目中已经开始使用了,并且这套框架应用到了项目整个UI端,服务端也是未稳定的web api,真心佩服团队

JSP隐式对象和MVC设计模式

 今天我们一起来了解一下关于JSP应用的JSP的隐式对像和MVC设计模式. 首先我们先来说一下JSP的隐式对象:JSP隐式对象是Web容器加载的一组类的实例.它是可以直接在JSP页面使用的对象.分为4个主要类别:1. 输入和输出对象:控制页面的输入和输出(request.response.out). 2. 作用域通信对象:检索与JSP页面的Servlet相关的信息(session.application.pageContext). 3. Servlet对象:提供有关页面环境的信息(page.co