javascript面向对象思想

js本身不是面向对象语言,在我们实际开发中其实很少用到面向对象思想,以前一直以为当要复用的时候才封装成对象,然而随着现在做的项目都后期测试阶段发现面向对象的作用不仅仅只是复用,可能你们会说面向对象还有继承,多态的概念,但在javascript里面多态的概念是不存在,而继承由于web页面的必须先下载js在运行导致js的继承不能像后台那么灵活而且js没有重载以及重写不方便(而且js中重写的意义不是很大),所以在js中很少用到面向对象,可能在一些插件中会看到对象的写法,写js的都会有同样的感觉在写一个插件的时候一般是先用面相过程把插件功能写出来,然后在重构改成对象的方法.但在实际项目开发中要求时间进度和开发成本很少会有那么宽松的时间让你先用面向过程实现功能在重构.实际开发中我们基本都是用面相过程写完就直接提交了.

这种写法发现一个问题就是,当你把这个页面的写完了之后过一段时间突然这个页面的功能需求或是页面布局要调整,你在看这个页面的代码,一下很难快速的把整个页面的代码逻辑步骤梳理清楚,我相信很多写前端都要同感吧! 举个例子:我几年前写的放大镜插件,现在我在放出来发现我写的这个插件在谷歌浏览器第一次渲染的时候没有效果,代码如下:

  1 /// <reference path="../jquery11.js" />
  2 (function ($) {
  3     $.fn.extend({
  4         jqoom: function (potions) {
  5             var settings = {
  6                 width: 350,
  7                 height: 350,
  8                 position: "right"
  9             }
 10             if (potions) {
 11                 $.extend(settings, potions);
 12             }
 13             var ImgUrl = $("img", this).attr("src");
 14             var ImgMinWidth = $("img", this).width();
 15             var ImgMinHeigth = $("img", this).height();
 16             var ImgWidth = 0;
 17             var ImgHeight = 0;
 18             var de = true;
 19
 20             $(this).hover(function (e) {
 21             }, function () {
 22                 $("#jqoomz").remove();
 23                 $(document).unbind("mousemove");
 24                 $("#jqoomy").remove();
 25
 26                 de = true;
 27             });
 28             $("img", this).hover(function (e) {
 29                 var pagex = e.x || e.pageX;
 30                 var pagey = e.y || e.pageY;
 31                 var pagex1 = 0;
 32                 var pagey1 = 0;
 33                 var leftcha = 0;
 34                 var topcha = 0;
 35                 _this = $(this).parents("div");
 36                 if ($("#jqoomz").length == 0) {
 37                     _this.after("<div id=‘jqoomz‘></div>");
 38                     var obj = new Image();
 39                     obj.src = ImgUrl;
 40                     obj.onload = function () {
 41                         if (de && obj.height > 0) {
 42                             de = false;
 43                             ImgWidth = obj.width;
 44                             ImgHeight = obj.height;
 45                             finder.call(_this.find("img")[0]);
 46                         }
 47                     };
 48                     $("#jqoomz").width(settings.width).height(settings.height).offset({
 49                         left: $(_this).outerWidth() + $(_this).offset().left,
 50                         top: $(_this)[0].offsetTop
 51                     }).append($("<img></img>").attr("src", ImgUrl));
 52                     if (de && obj.height > 0) {
 53                         de = false;
 54                         ImgWidth = obj.width;
 55                         ImgHeight = obj.height;
 56                         finder.call(this);
 57                     }
 58                 }
 59                 function mover(event) {
 60                     var pagex2 = event.x || event.pageX;
 61                     var pagey2 = event.y || event.pageY;
 62                     if (parseInt(pagex2 + leftcha) <= parseInt($(_this).width() + $(_this).offset().left) && pagex2 >= leftcha + $(_this).offset().left) {
 63                         $(this).offset({left: pagex2 - leftcha});
 64                     } else {
 65                         if (parseInt(pagex2 + leftcha) > parseInt($(_this).width() + $(_this).offset().left) && pagex2)
 66                             $(this).offset({left: $(_this).width() + $(_this).offset().left - leftcha * 2});
 67                         else
 68                             $(this).offset({left: $(_this).offset().left});
 69                     }
 70                     if (parseInt(pagey2 + topcha) <= parseInt($(_this).height() + $(_this).offset().top) && pagey2 >= topcha + $(_this).offset().top) {
 71                         $(this).offset({top: (pagey2 - topcha)});
 72                         //document.getElementById("move").style.top = (pagey2 - (this.pagey - this.divtop)).toString() + "px";
 73                     } else {
 74                         if (parseInt(pagey2 + topcha) > parseInt($(_this).height() + $(_this).offset().top))
 75                             $(this).offset({top: ($(_this).height() + $(_this).offset().top - topcha * 2)});
 76                         //document.getElementById("move").style.top = (this.height - this.divHeight).toString() + "px";
 77                         else
 78                             $(this).offset({top: $(_this).offset().top});
 79                         //document.getElementById("move").style.top = "0px"
 80                     }
 81                     var bilx = ($(this).offset().left - $(_this).offset().left) / (ImgMinWidth / ImgWidth);
 82                     var bily = ($(this).offset().top - $(_this).offset().top) / (ImgMinHeigth / ImgHeight);
 83                     $("#jqoomz img").css({"margin-left": -bilx, "margin-top": -bily});
 84                 }
 85
 86                 function finder() {
 87                     if (parseFloat($(this).offset().top + $(this).height() - (ImgMinHeigth / ImgHeight * ImgMinHeigth)) >=
 88                         parseFloat(pagey - ImgMinHeigth / ImgHeight * ImgMinHeigth / 2) && parseFloat(pagey - ImgMinHeigth / ImgHeight * ImgMinHeigth / 2) >=
 89                         parseFloat($(this).offset().top)) {
 90                         pagey1 = (pagey - ImgMinHeigth / ImgHeight * ImgMinHeigth / 2);
 91                     } else {
 92                         if ((pagey - ImgMinHeigth / ImgHeight * ImgMinHeigth / 2) < $(this).offset().top) {
 93                             pagey1 = $(this).offset().top;
 94                         } else {
 95                             pagey1 = ($(this).offset().top + $(this).height() - (ImgMinHeigth / ImgHeight * ImgMinHeigth));
 96                         }
 97                     }
 98                     if (($(this).offset().left + $(this).width() - ImgMinWidth / ImgWidth * ImgMinWidth) >=
 99                         (pagex - ImgMinWidth / ImgWidth * ImgMinWidth / 2) && (pagex - ImgMinWidth / ImgWidth * ImgMinWidth / 2) >=
100                         $(this).offset().left) {
101                         pagex1 = (pagex - ImgMinWidth / ImgWidth * ImgMinWidth / 2);
102                     } else {
103                         if ((pagex - ImgMinWidth / ImgWidth * ImgMinWidth / 2) < $(this).offset().left) {
104                             pagex1 = $(this).offset().left;
105                         } else {
106                             pagex1 = ($(this).offset().left + $(this).width() - ImgMinWidth / ImgWidth * ImgMinWidth);
107                         }
108                     }
109                     leftcha = ImgMinWidth / ImgWidth * ImgMinWidth / 2;
110                     topcha = ImgMinHeigth / ImgHeight * ImgMinHeigth / 2;
111                     if ($("#jqoomy").length == 0) {
112                         $(this).after("<div id=‘jqoomy‘></div>")
113                             .siblings("#jqoomy")
114                             .addClass("jqoomy").show()
115                             .width((ImgMinWidth / ImgWidth * ImgMinWidth))
116                             .height((ImgMinHeigth / ImgHeight * ImgMinHeigth)).offset({
117                             top: pagey1,
118                             left: pagex1
119                         });
120                     }
121                     $(document).on("mousemove", $.proxy(mover, $("#jqoomy")));
122                 }
123             }, function () {
124             });
125         }
126     });
127 })(jQuery);

html:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <script src="jquery11.js"></script>
    <script src="OppJqoom.js"></script>
    <style type="text/css">
        .jqoom
        {
            width: 350px;
            height: 350px;
            border: solid 1px #DFDFDF;
            z-index: 10;
        }

            .jqoom img
            {
                cursor: pointer;
                z-index: 10;
                max-height: 350px;
                max-width: 350px;
            }

        .jqoomy
        {
            background-color: white;
            position: relative;
            z-index: 999;
            opacity: 0.5;
            cursor: pointer;
            border: solid 1px #DFDFDF;
        }

        #jqoomz
        {
            border: solid 1px #DFDFDF;
            position: absolute;
            overflow: hidden;
        }

        .lef
        {
            border: 1px solid #DFDFDF;
            display: block;
            height: 72px;
            line-height: 72px;
            text-align: center;
            text-decoration: none;
            width: 10px;
            background-color:#EBEBEB;
            float:left;
        }
            .lef:hover
            {
                color:red;
            }
        .jqooz
        {
            float:left;
            width:352px;
            margin-top:20px;
        }
            .jqooz ul
            {
                 float: left;
                 margin: 0;
                 padding: 0;
                 width:328px;
                 height:72px;
            }
                .jqooz ul li
                {
                    display: inline;
                    list-style: none outside none;
                    margin: 0 10px;
                }
                    .jqooz ul li img
                    {
                        border: 1px solid #DFDFDF;
                        max-height: 72px;
                        max-width: 120px;
                    }
                        .jqooz ul li img:hover
                        {
                            border: 1px solid #ff6600;
                        }
    </style>
    <script type="text/javascript">
        $(function () {
            $(".jqoom").jqoom();
        });

    </script>
</head>
<body>
    <div class="jqoom">
        <img src="b3.jpg" />
    </div>
    <div class="jqooz">
    <a href="javascript:void(0)" class="lef"><</a>
        <ul>
            <li><a>
                <img src="b3.jpg" /></a></li>
        </ul>
        <a href="javascript:void(0)" class="lef">></a>
        </div>
</body>
</html>

效果:

现在我要修改这个插件为什么在谷歌浏览器第一次加载的时候没有效果,那我要重新跟着代码来梳理放大镜里面的整个功能步骤,这个放大镜的功能还不是很复杂,在实际项目中各种函数回调嵌套,取数,数据处理,显示,页面的动态效果都交织在onload或是ready里面你要花几个小时甚至一整天来梳理你要修改页面的代码逻辑,而且还未必能梳理的全面,所以经常会有前端同事在隔了一段时间给之前写的页面添加注释的时候说我自己写代码都开始看不懂了.

本身javascript特点之一是事件监听函数回调,这是它优点,nodejs作者之所以选择js其中一个原因就是javascript的事件监听函数回调带来的优点,但函数回调同时也带来一个缺点就是经常出现return不出数据,典型的例子就是ajax,jQuery传统的ajax成功之后回调success方法,当你要把这个ajax的输出作为另一个ajax的输入的时候你就不得不要嵌套ajax,一旦嵌套多了这个代码的可读性和复杂度就增加了很多!后期的维护也自然增加了难度,Promise出来之后,jQuery、angular也都纷纷加了Promise。为什么javascript在后期维护要花这么大的时间去梳理逻辑?

我们在看看后台java或c#的语言是怎么做,典型的javaweb几乎都是springMVC框架,C#做web毋庸置疑是.net MVC,他们都有共同的特点是c层提供给前台页面ajax调用的方法都是按照所需要的数据一个一个拆分的,还有相对于的m层,mvc其实是两个维度的分层这是我个人观点,一个维度是单个细小的功能分为view,control,model,另一个维度是整个页面分成多个小的功能.所以你发现后台代码要修改其实很容易就把逻辑梳理,那前台javascript也能不能按照整个思路来取分层呢?

这个插件没有涉及到动态取数,所以分层的标准也不一样,在这里我分了两层,第一层是对鼠标移动后图片的一系列算法,第二层是事件绑定分的一系列dom的操作,代码如下:

/**
 * Created by  on 2016/11/2.
 */
(function ($) {
    //构造函数逻辑主线路
    var OppJqoom = function (_this, potions) {
        this._this = _this;
        this.ImgUrl = $("img", this._this).attr("src");
        this.ImgMinWidth = $("img", this._this).width();
        this.ImgMinHeigth = $("img", this._this).height();
        this.ImgWidth ,this.ImgHeight ,this.leftcha,this.topcha;
        var settings = {
            width: 350,
            height: 350,
            position: "right"
        }
        $.extend(this,settings);
        if (potions) {
            $.extend(this, potions);
        }
        this.domOperation.Jqoomhover.call(this);
        this.domOperation.imghover.call(this);

    };
    OppJqoom.prototype = {
        // 第一层 算法层
        basicOperation: {
           /* 获取遮罩层的top和left*/
            finder: function (that) {
                var pagey1, pagex1;
                if (parseFloat($(this).offset().top + $(this).height() - (that.ImgMinHeigth / that.ImgHeight * that.ImgMinHeigth)) >=
                    parseFloat(this.pagey - that.ImgMinHeigth / that.ImgHeight * that.ImgMinHeigth / 2) && parseFloat(this.pagey - that.ImgMinHeigth / that.ImgHeight * that.ImgMinHeigth / 2) >=
                    parseFloat($(this).offset().top)) {
                    pagey1 = (this.pagey - that.ImgMinHeigth / that.ImgHeight * that.ImgMinHeigth / 2);
                } else {
                    if ((this.pagey - that.ImgMinHeigth / that.ImgHeight * that.ImgMinHeigth / 2) < $(this).offset().top) {
                        pagey1 = $(this).offset().top;
                    } else {
                        pagey1 = ($(this).offset().top + $(this).height() - (that.ImgMinHeigth / that.ImgHeight * that.ImgMinHeigth));
                    }
                }
                if (($(this).offset().left + $(this).width() - that.ImgMinWidth / that.ImgWidth * that.ImgMinWidth) >=
                    (this.pagex - that.ImgMinWidth / that.ImgWidth * that.ImgMinWidth / 2) && (this.pagex - that.ImgMinWidth / that.ImgWidth * that.ImgMinWidth / 2) >=
                    $(this).offset().left) {
                    pagex1 = (this.pagex - that.ImgMinWidth / that.ImgWidth * that.ImgMinWidth / 2);
                } else {
                    if ((this.pagex - that.ImgMinWidth / that.ImgWidth * that.ImgMinWidth / 2) < $(this).offset().left) {
                        pagex1 = $(this).offset().left;
                    } else {
                        pagex1 = ($(this).offset().left + $(this).width() - that.ImgMinWidth / that.ImgWidth * that.ImgMinWidth);
                    }
                }
                that.leftcha = that.ImgMinWidth / that.ImgWidth * that.ImgMinWidth / 2;
                that.topcha = that.ImgMinHeigth / that.ImgHeight * that.ImgMinHeigth / 2;
                that.domOperation.docMousemove.call(that);
                return {top: pagey1, left: pagex1};

            },
            // 放大镜的图片的top和left
            mover: function (that) {
                if (parseInt(that.pagex2 + that.leftcha) <= parseInt(that._this.width() + that._this.offset().left) && that.pagex2 >= that.leftcha + that._this.offset().left) {
                    $(this).offset({left: that.pagex2 - that.leftcha});
                } else {
                    if (parseInt(that.pagex2 + that.leftcha) > parseInt(that._this.width() + that._this.offset().left) && that.pagex2)
                        $(this).offset({left: that._this.width() + that._this.offset().left - that.leftcha * 2});
                    else
                        $(this).offset({left: that._this.offset().left});
                }
                if (parseInt(that.pagey2 + that.topcha) <= parseInt(that._this.height() + that._this.offset().top) && that.pagey2 >= that.topcha + that._this.offset().top) {
                    $(this).offset({top: (that.pagey2 - that.topcha)});
                    //document.getElementById("move").style.top = (pagey2 - (this.pagey - this.divtop)).toString() + "px";
                } else {
                    if (parseInt(that.pagey2 + that.topcha) > parseInt(that._this.height() + that._this.offset().top))
                        $(this).offset({top: (that._this.height() + that._this.offset().top - that.topcha * 2)});
                    //document.getElementById("move").style.top = (this.height - this.divHeight).toString() + "px";
                    else
                        $(this).offset({top: that._this.offset().top});
                    //document.getElementById("move").style.top = "0px"
                }
                var bilx = ($(this).offset().left - that._this.offset().left) / (that.ImgMinWidth / that.ImgWidth);
                var bily = ($(this).offset().top - that._this.offset().top) / (that.ImgMinHeigth / that.ImgHeight);
                return{left:bilx,top:bily};
            }
        },
        // 第二层 事件绑定层
        domOperation: {
            // 鼠标移动到图片的一系列dom的操作
            imghover: function () {
                var that = this;
                $("img", this._this).hover(function (e) {
                    this.pagex = e.x || e.pageX;
                    this.pagey = e.y || e.pageY;
                    var offset;
                    var obj = new Image();
                    obj.src = that.ImgUrl;
                    obj.onload = function () {
                        if (obj.height > 0) {
                            that.ImgWidth = obj.width;
                            that.ImgHeight = obj.height;
                            if ($("#jqoomz").length == 0) {
                                that._this.after("<div id=‘jqoomz‘></div>");
                            }
                            offset = that.basicOperation.finder.call(that._this.find("img")[0],that);
                        }
                    };
                    if ($("#jqoomz").length == 0) {
                        that.ImgWidth = obj.width;
                        that.ImgHeight = obj.height;
                        that._this.after("<div id=‘jqoomz‘></div>");
                    }
                    offset = that.basicOperation.finder.call(this,that);
                    if ($("#jqoomy").length == 0) {
                        $(this).after("<div id=‘jqoomy‘></div>")
                            .siblings("#jqoomy")
                            .addClass("jqoomy")
                            .show()
                            .width((that.ImgMinWidth / that.ImgWidth * that.ImgMinWidth))
                            .height((that.ImgMinHeigth / that.ImgHeight * that.ImgMinHeigth))
                            .offset({
                                top: offset.top,
                                left: offset.left
                            });
                    }
                    $("#jqoomz").width(that.width).height(that.height).offset({
                        left: that._this.outerWidth() + that._this.offset().left,
                        top: that._this[0].offsetTop
                    }).append($("<img></img>").attr("src", that.ImgUrl));
                },function () {});
            },
            //鼠标在图片上滑动的一系列dom操作
            docMousemove: function () {
                var that=this;
                $(document).on("mousemove", function (event) {
                    that.pagex2 = event.x || event.pageX;
                    that.pagey2 = event.y || event.pageY;
                    var offset=that.basicOperation.mover.call($("#jqoomy"),that);
                    $("#jqoomz img").css({"margin-left": -offset.left, "margin-top": -offset.top});
                });
            },
            //鼠标移除图片的一系列dom操作
            Jqoomhover:function () {
                this._this.hover(function (e) {
                }, function () {
                    console.log(111);
                    $("#jqoomz").remove();
                    $(document).unbind("mousemove");
                    $("#jqoomy").remove();
                });
            }
        }
    };
    $.fn.extend({
        jqoom: function (potions) {
            return new OppJqoom(this, potions);
        }
    })
})(jQuery);

然后加上简单的注释感觉页面的逻辑步骤就很清晰了,当然这种写法一种比较麻烦的就是this的用法,对象中嵌套对象调用里面的方法this是指向自己的对象.

在实际开发中我们可以分为数据读取层,数据处理层,以及dom动态效果层,如果业务比较繁杂也可以在分个数据展现层.

当然这是我个人的理解,可能有很多方面没考虑到,只是提供了一些思路!

时间: 2024-10-13 06:10:50

javascript面向对象思想的相关文章

javascript面向对象思想做form表单验证 代码很精简哦

<html> <head> <meta charset=utf-8 /> <!--引入jQuery--> <!--coder:[email protected] 孙亚龙---> <script src="jquery-1.7.2.min.js"></script> <script> var obj = { res : true , nick_fun : function(o,tip){ if

JavaScript 面向对象思想 贪吃蛇游戏

js代码: 游戏的对象 ,食物,蛇 ,游戏控制思路如下 (完整代码在https://github.com/774044859yf/ObjectSnakeGame下载) var snake = { aSnake: [],//添加蛇的数组 size: 20,//蛇的大小,每块身体的size top: 200,//初始位置 left: 400,//初始位置 speed: 250,//初始速度 level: 1,//初始游戏等级 len: 3,//蛇身长度默认3个单位 direction: 'left'

[Javascript] 面向对象编程思想

1.创建对象 1.1 new 用new进行创建对象: var user = new Object(); user.age = 12;//同时为对象添加属性 user.name = 'ajun'; 1.2{} 用{}创建对象,如: var user = { 'name':'ajun, 'age':12 } 这里同时候为user添加了两个属性分别为:name,age 在以上代码稍加改造,你还可以为一个对象添加一个方法,如: var user = { 'name':'ajun', 'age':12 '

聚焦JavaScript面向对象的思想

面向对象是一种软件开发方法,是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物.随着时代的发展,计算机被用于解决越来越复杂的问题.一切事物皆对象,通过面向对象的方式,将现实世界的事物抽象成对象.通过面向对象的方法,更利于用人理解的方式对复杂系统进行分析.设计与编程,今天我们就来学习一下JavaScript面向对象的思想. 面向过程和面向对象编程概述面向过程编程就是分析出解决问题的步骤,然后使用函数把这些步骤一步步实现,重心放在完成的每个过程上.面向对象则是以封装的思想,将问

JavaScript面向对象旅程(下)

JavaScript面向对象旅程 剪不断,理还乱,是离愁. 前面已经提到过新语言开发的两个步骤,分别是:一.定义基本的数据类型,完善结构化编程语言的设计:二.为函数类型绑定this的概念,好在对象的方法中可以引用到对象自身.下面是继续下去的思路,其主体思想是尽可能地引用传统面向对象语言的相关概念(如类.继承等)到新语言中来. 三.让对象属于某个类 这次要引入类的概念来.但是注意的是,还是前面提到过的思路,是让对象看起来属于某个类,而不是真正地构造基于类的种种语义概念. 一般来说,类包括类符号和类

JavaScript 面向对象 (prototype 原型模式)

一. JavaScript 设计思想 1994年,网景公司(Netscape)发布了Navigator浏览器0.9版.这是历史上第一个比较成熟的网络浏览器,轰动一时.但是,这个版本的浏览器只能用来浏览,不具备与访问者互动的能力.比如,如果网页上有一栏"用户名"要求填写,浏览器就无法判断访问者是否真的填写了,只有让服务器端判断.如果没有填写,服务器端就返回错误,要求用户重新填写,这太浪费时间和服务器资源了. 因此,网景公司急需一种网页脚本语言,使得浏览器可以与网页互动.工程师_Brend

使用面向对象思想处理cookie

实例:使用面向对象思想处理cookie如果读者对cookie 不熟悉,可以在第七章学习它的使用方法,虽然在那里创建了几个通用函数用于cookie 的处理,但这些函数彼此分离,没有体现出是一个整体.联想到JavaScript中Math对象的功能,它其实就是通过Math这个全局对象,把所有的数学计算相关的常量和方法都联系到一起,作为一个整体使用,提高了封装性和使用效率.现在对cookie的处理事实上也可以按照这种方法来进行.6.9.1 需求分析对于cookie 的处理,事实上只是封装一些方法,每个对

javascript面向对象分层思维

js本身不是面向对象语言,在我们实际开发中其实很少用到面向对象思想,以前一直以为当要复用的时候才封装成对象,然而随着现在做的项目都后期测试阶段发现面向对象的作用不仅仅只是复用,可能你们会说面向对象还有继承,多态的概念,但在javascript里面多态的概念是不存在,而继承由于web页面的必须先下载js在运行导致js的继承不能像后台那么灵活而且js没有重载以及重写不方便(而且js中重写的意义不是很大),所以在js中很少用到面向对象,可能在一些插件中会看到对象的写法,写js的都会有同样的感觉在写一个

js之JavaScript 面向对象介绍 ----谷营中西软件科技园

1. 面向对象介绍 1.1. 对象 在面向对象思想中,一切皆对象.所谓的对象,实质上是指"事物"(包括人和物)在程序设计 语言中的表现形式.这里的"事物"可以是任何东西.例如,我们将一名女生作为对象的话,那么她 可能是一名美丽的.高挑的.可爱的等等,这些形容这名女生的词,我们就叫做属性.那么她可能要 上学.工作.出国等等,这些女生要做的事情,我们就叫做方法. 所以,简单来说对象,可以这样描述.我们将世界上任何的人和物都理解成对象,用来描述对象 的特征叫做属性,用来描