搜尋
首頁web前端js教程JavaScript物件導向分層思維全面解析

js本身不是面向對象語言,在我們實際開發中其實很少用到面向對象思想,以前一直以為當要復用的時候才封裝成對象,然而隨著現在做的項目都後期測試階段發現面向對象的作用不隻隻是複用,可能你們會說面向對象還有繼承,多態的概念,但在javascript裡面多態的概念是不存在,而繼承由於web頁面的必須先下載js在運行導致js的繼承不能像後台那麼靈活而且js沒有重載以及重寫不方便(而且js中重寫的意義不是很大),所以在js中很少用到面向對象,可能在一些插件中會看到對象的寫法,寫js的都會有同樣的感覺在寫一個插件的時候一般是先用面相過程把插件功能寫出來,然後在重構改成對象的方法.但在實際專案開發中要求時間進度和開發成本很少會有那麼寬鬆的時間讓你先用面向過程實現功能在重構.實際開發中我們基本都是用面相過程寫完就直接提交了.

這種寫法發現一個問題就是,當你把這個頁面的寫完了之後過一段時間突然這個頁面的功能需求或是頁面佈局要調整,你在看這個頁面的代碼,一下很難快速的把整個頁面的代碼邏輯步驟梳理清楚,我相信很多寫前端都要同感吧! 舉個例子:我幾年前寫的放大鏡插件,現在我在放出來發現我寫的這個插件在谷歌瀏覽器第一次渲染的時候沒有效果,代碼如下:

/// <reference path="../jquery11.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("<div id=&#39;jqoomz&#39;></div>");
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($("<img  src="/static/imghwm/default1.png"  data-src="jquery11.js"  class="lazy"  alt="JavaScript物件導向分層思維全面解析" ></img>").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("<div id=&#39;jqoomy&#39;></div>")
.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:

<!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 ></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="/static/imghwm/default1.png"  data-src="b3.jpg"  class="lazy"   / alt="JavaScript物件導向分層思維全面解析" >
</div>
<div class="jqooz">
<a href="javascript:void(0)" class="lef"><</a>
<ul>
<li><a>
<img  src="/static/imghwm/default1.png"  data-src="b3.jpg"  class="lazy"   / alt="JavaScript物件導向分層思維全面解析" ></a></li>
</ul>
<a href="javascript:void(0)" class="lef">></a>
</div>
</body>
</html>

   

效果:

JavaScript物件導向分層思維全面解析

現在我要修改這個插件為什麼在谷歌瀏覽器第一次加載的時候沒有效果,那我要重新跟著代碼來放大的整個程式碼來放大這個過程放大鏡的功能還不是很複雜,在實際項目中各種函數回調嵌套,取數,數據處理,顯示,頁面的動態效果都交織在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=&#39;jqoomz&#39;></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=&#39;jqoomz&#39;></div>");
}
offset = that.basicOperation.finder.call(this,that);
if ($("#jqoomy").length == 0) {
$(this).after("<div id=&#39;jqoomy&#39;></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  alt="JavaScript物件導向分層思維全面解析" ></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動態效果層,如果業務比較繁雜也可以在分個資料展現層.


陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JavaScript,C和瀏覽器之間的關係JavaScript,C和瀏覽器之間的關係May 01, 2025 am 12:06 AM

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr

node.js流帶打字稿node.js流帶打字稿Apr 30, 2025 am 08:22 AM

Node.js擅長於高效I/O,這在很大程度上要歸功於流。 流媒體匯總處理數據,避免內存過載 - 大型文件,網絡任務和實時應用程序的理想。將流與打字稿的類型安全結合起來創建POWE

Python vs. JavaScript:性能和效率注意事項Python vs. JavaScript:性能和效率注意事項Apr 30, 2025 am 12:08 AM

Python和JavaScript在性能和效率方面的差異主要體現在:1)Python作為解釋型語言,運行速度較慢,但開發效率高,適合快速原型開發;2)JavaScript在瀏覽器中受限於單線程,但在Node.js中可利用多線程和異步I/O提升性能,兩者在實際項目中各有優勢。

JavaScript的起源:探索其實施語言JavaScript的起源:探索其實施語言Apr 29, 2025 am 12:51 AM

JavaScript起源於1995年,由布蘭登·艾克創造,實現語言為C語言。 1.C語言為JavaScript提供了高性能和系統級編程能力。 2.JavaScript的內存管理和性能優化依賴於C語言。 3.C語言的跨平台特性幫助JavaScript在不同操作系統上高效運行。

幕後:什麼語言能力JavaScript?幕後:什麼語言能力JavaScript?Apr 28, 2025 am 12:01 AM

JavaScript在瀏覽器和Node.js環境中運行,依賴JavaScript引擎解析和執行代碼。 1)解析階段生成抽象語法樹(AST);2)編譯階段將AST轉換為字節碼或機器碼;3)執行階段執行編譯後的代碼。

Python和JavaScript的未來:趨勢和預測Python和JavaScript的未來:趨勢和預測Apr 27, 2025 am 12:21 AM

Python和JavaScript的未來趨勢包括:1.Python將鞏固在科學計算和AI領域的地位,2.JavaScript將推動Web技術發展,3.跨平台開發將成為熱門,4.性能優化將是重點。兩者都將繼續在各自領域擴展應用場景,並在性能上有更多突破。

Python vs. JavaScript:開發環境和工具Python vs. JavaScript:開發環境和工具Apr 26, 2025 am 12:09 AM

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

JavaScript是用C編寫的嗎?檢查證據JavaScript是用C編寫的嗎?檢查證據Apr 25, 2025 am 12:15 AM

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器