0

0

JavaScript面向对象分层思维全面解析

高洛峰

高洛峰

发布时间:2016-12-05 16:17:04

|

1107人浏览过

|

来源于php中文网

原创

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

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

/// 
(function ($) {
$.fn.extend({
jqoom: function (potions) {
var settings = {
width: 350,
height: 350,
position: "right"
}
if (potions) {
$.extend(settings, potions);
}
var ImgUrl = $("img", this).attr("src");
var ImgMinWidth = $("img", this).width();
var ImgMinHeigth = $("img", this).height();
var ImgWidth = 0;
var ImgHeight = 0;
var de = true;
$(this).hover(function (e) {
}, function () {
$("#jqoomz").remove();
$(document).unbind("mousemove");
$("#jqoomy").remove();
de = true;
});
$("img", this).hover(function (e) {
var pagex = e.x || e.pageX;
var pagey = e.y || e.pageY;
var pagex1 = 0;
var pagey1 = 0;
var leftcha = 0;
var topcha = 0;
_this = $(this).parents("div");
if ($("#jqoomz").length == 0) {
_this.after("
"); var obj = new Image(); obj.src = ImgUrl; obj.onload = function () { if (de && obj.height > 0) { de = false; ImgWidth = obj.width; ImgHeight = obj.height; finder.call(_this.find("img")[0]); } }; $("#jqoomz").width(settings.width).height(settings.height).offset({ left: $(_this).outerWidth() + $(_this).offset().left, top: $(_this)[0].offsetTop }).append($("@@##@@").attr("src", ImgUrl)); if (de && obj.height > 0) { de = false; ImgWidth = obj.width; ImgHeight = obj.height; finder.call(this); } } function mover(event) { var pagex2 = event.x || event.pageX; var pagey2 = event.y || event.pageY; if (parseInt(pagex2 + leftcha) <= parseInt($(_this).width() + $(_this).offset().left) && pagex2 >= leftcha + $(_this).offset().left) { $(this).offset({left: pagex2 - leftcha}); } else { if (parseInt(pagex2 + leftcha) > parseInt($(_this).width() + $(_this).offset().left) && pagex2) $(this).offset({left: $(_this).width() + $(_this).offset().left - leftcha * 2}); else $(this).offset({left: $(_this).offset().left}); } if (parseInt(pagey2 + topcha) <= parseInt($(_this).height() + $(_this).offset().top) && pagey2 >= topcha + $(_this).offset().top) { $(this).offset({top: (pagey2 - topcha)}); //document.getElementById("move").style.top = (pagey2 - (this.pagey - this.divtop)).toString() + "px"; } else { if (parseInt(pagey2 + topcha) > parseInt($(_this).height() + $(_this).offset().top)) $(this).offset({top: ($(_this).height() + $(_this).offset().top - topcha * 2)}); //document.getElementById("move").style.top = (this.height - this.divHeight).toString() + "px"; else $(this).offset({top: $(_this).offset().top}); //document.getElementById("move").style.top = "0px" } var bilx = ($(this).offset().left - $(_this).offset().left) / (ImgMinWidth / ImgWidth); var bily = ($(this).offset().top - $(_this).offset().top) / (ImgMinHeigth / ImgHeight); $("#jqoomz img").css({"margin-left": -bilx, "margin-top": -bily}); } function finder() { if (parseFloat($(this).offset().top + $(this).height() - (ImgMinHeigth / ImgHeight * ImgMinHeigth)) >= parseFloat(pagey - ImgMinHeigth / ImgHeight * ImgMinHeigth / 2) && parseFloat(pagey - ImgMinHeigth / ImgHeight * ImgMinHeigth / 2) >= parseFloat($(this).offset().top)) { pagey1 = (pagey - ImgMinHeigth / ImgHeight * ImgMinHeigth / 2); } else { if ((pagey - ImgMinHeigth / ImgHeight * ImgMinHeigth / 2) < $(this).offset().top) { pagey1 = $(this).offset().top; } else { pagey1 = ($(this).offset().top + $(this).height() - (ImgMinHeigth / ImgHeight * ImgMinHeigth)); } } if (($(this).offset().left + $(this).width() - ImgMinWidth / ImgWidth * ImgMinWidth) >= (pagex - ImgMinWidth / ImgWidth * ImgMinWidth / 2) && (pagex - ImgMinWidth / ImgWidth * ImgMinWidth / 2) >= $(this).offset().left) { pagex1 = (pagex - ImgMinWidth / ImgWidth * ImgMinWidth / 2); } else { if ((pagex - ImgMinWidth / ImgWidth * ImgMinWidth / 2) < $(this).offset().left) { pagex1 = $(this).offset().left; } else { pagex1 = ($(this).offset().left + $(this).width() - ImgMinWidth / ImgWidth * ImgMinWidth); } } leftcha = ImgMinWidth / ImgWidth * ImgMinWidth / 2; topcha = ImgMinHeigth / ImgHeight * ImgMinHeigth / 2; if ($("#jqoomy").length == 0) { $(this).after("
") .siblings("#jqoomy") .addClass("jqoomy").show() .width((ImgMinWidth / ImgWidth * ImgMinWidth)) .height((ImgMinHeigth / ImgHeight * ImgMinHeigth)).offset({ top: pagey1, left: pagex1 }); } $(document).on("mousemove", $.proxy(mover, $("#jqoomy"))); } }, function () { }); } }); })(jQuery);

   html:












@@##@@

   

立即学习Java免费学习笔记(深入)”;

效果:

JavaScript面向对象分层思维全面解析

Color Wheel
Color Wheel

AI灰度logo或插画上色工具

下载

现在我要修改这个插件为什么在谷歌浏览器第一次加载的时候没有效果,那我要重新跟着代码来梳理放大镜里面的整个功能步骤,这个放大镜的功能还不是很复杂,在实际项目中各种函数回调嵌套,取数,数据处理,显示,页面的动态效果都交织在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("
"); } 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("
"); } offset = that.basicOperation.finder.call(this,that); if ($("#jqoomy").length == 0) { $(this).after("
") .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($("@@##@@").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动态效果层,如果业务比较繁杂也可以在分个数据展现层.

JavaScript面向对象分层思维全面解析JavaScript面向对象分层思维全面解析22.pngJavaScript面向对象分层思维全面解析

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
全国统一发票查询平台入口合集
全国统一发票查询平台入口合集

本专题整合了全国统一发票查询入口地址合集,阅读专题下面的文章了解更多详细入口。

19

2026.02.03

短剧入口地址汇总
短剧入口地址汇总

本专题整合了短剧app推荐平台,阅读专题下面的文章了解更多详细入口。

27

2026.02.03

植物大战僵尸版本入口地址汇总
植物大战僵尸版本入口地址汇总

本专题整合了植物大战僵尸版本入口地址汇总,前往文章中寻找想要的答案。

15

2026.02.03

c语言中/相关合集
c语言中/相关合集

本专题整合了c语言中/的用法、含义解释。阅读专题下面的文章了解更多详细内容。

3

2026.02.03

漫蛙漫画网页版入口与正版在线阅读 漫蛙MANWA官网访问专题
漫蛙漫画网页版入口与正版在线阅读 漫蛙MANWA官网访问专题

本专题围绕漫蛙漫画(Manwa / Manwa2)官网网页版入口进行整理,涵盖漫蛙漫画官方主页访问方式、网页版在线阅读入口、台版正版漫画浏览说明及基础使用指引,帮助用户快速进入漫蛙漫画官网,稳定在线阅读正版漫画内容,避免误入非官方页面。

13

2026.02.03

Yandex官网入口与俄罗斯搜索引擎访问指南 Yandex中文登录与网页版入口
Yandex官网入口与俄罗斯搜索引擎访问指南 Yandex中文登录与网页版入口

本专题汇总了俄罗斯知名搜索引擎 Yandex 的官网入口、免登录访问地址、中文登录方法与网页版使用指南,帮助用户稳定访问 Yandex 官网,并提供一站式入口汇总。无论是登录入口还是在线搜索,用户都能快速获取最新稳定的访问链接与使用指南。

114

2026.02.03

Java 设计模式与重构实践
Java 设计模式与重构实践

本专题专注讲解 Java 中常用的设计模式,包括单例模式、工厂模式、观察者模式、策略模式等,并结合代码重构实践,帮助学习者掌握 如何运用设计模式优化代码结构,提高代码的可读性、可维护性和扩展性。通过具体示例,展示设计模式如何解决实际开发中的复杂问题。

3

2026.02.03

C# 并发与异步编程
C# 并发与异步编程

本专题系统讲解 C# 异步编程与并发控制,重点介绍 async 和 await 关键字、Task 类、线程池管理、并发数据结构、死锁与线程安全问题。通过多个实战项目,帮助学习者掌握 如何在 C# 中编写高效的异步代码,提升应用的并发性能与响应速度。

2

2026.02.03

Python 强化学习与深度Q网络(DQN)
Python 强化学习与深度Q网络(DQN)

本专题深入讲解 Python 在强化学习(Reinforcement Learning)中的应用,重点介绍 深度Q网络(DQN) 及其实现方法,涵盖 Q-learning 算法、深度学习与神经网络的结合、环境模拟与奖励机制设计、探索与利用的平衡等。通过构建一个简单的游戏AI,帮助学习者掌握 如何使用 Python 训练智能体在动态环境中作出决策。

3

2026.02.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.6万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.7万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号