前端學習--js.2
- 寫一個通用的事件偵聽器函式
- markyun.Event = {
- // 頁面載入完成後
- readyEvent : function(fn) {
- if (fn==
- fn=document;
- }
- var oldonload = window.onload;
- if (typeof window.onload != 'function') {
- window.onload = fn;
- }
- window.onload = function() {
- oldonload();
- fn();
- };
- }
- },
- // 視能力分別使用dom0||dom2||IE方式 來繫結事件
- // 引數: 操作的元素,事件名稱 ,事件處理程式
- addEvent : function(element, type, handler) {
- if (element.addEventListener) {
- //事件型別、需要執行的函式、是否捕捉
- element.addEventListener(type, handler, false);
- } else if (element.attachEvent) {
- element.attachEvent('on' + type, function() {
- handler.call(element);
- });
- } else {
- element['on' + type] = handler;
- }
- },
- // 移除事件
- removeEvent : function(element, type, handler) {
- if (element.removeEnentListener) {
- element.removeEnentListener(type, handler, false);
- } else if (element.datachEvent) {
- element.detachEvent('on' + type, handler);
- } else {
- element['on' + type] = null;
- }
- },
- // 阻止事件 (主要是事件冒泡,因為IE不支援事件捕獲)
- stopPropagation : function(ev) {
- if (ev.stopPropagation) {
- ev.stopPropagation();
- } else {
- ev.cancelBubble = true;
- }
- },
- // 取消事件的預設行為
- preventDefault : function(event) {
- if (event.preventDefault) {
- event.preventDefault();
- } else {
- event.returnValue = false;
- }
- },
- // 獲取事件目標
- getTarget : function(event) {
- return event.target || event.srcElement;
- },
- // 獲取event物件的引用,取到事件的所有資訊,確保隨時能使用event;
- getEvent : function(e) {
- var ev = e || window.event;
- if (!ev) {
- var c = this.getEvent.caller;
- while (c) {
- ev = c.arguments[0];
- if (ev && Event == ev.constructor) {
- break;
- }
- c = c.caller;
- }
- }
- return ev;
- }
- };
67、["1", "2", "3"].map(parseInt) 答案是多少?
[1,NaN,NaN]
68、關於事件,IE與火狐的事件機制有什麼區別? 如何阻止冒泡?
我們在網頁中的某個操作(有的操作對應多個事件)。例如:當我們點選一個按鈕就會產生一個事件。是可以被 JavaScript 偵測到的行為。
事件處理機制:IE是事件冒泡、火狐是 事件捕獲;
ev.stopPropagation();
69、什麼是閉包(closure),為什麼要用它?
閉包是指有權訪問另一個函式作用域中變數的函式,建立閉包的最常見的方式就是在一個函式內建立另一個函式,通過另一個函式訪問這個函式的區域性變數,利用閉包可以突破作用鏈域,將函式內部的變數和方法傳遞到外部。
閉包的特性:
(1)函式內再巢狀函式
(2)內部函式可以引用外層的引數和變數
(3)引數和變數不會被垃圾回收機制回收
HTML:
<!-- li節點的onclick事件都能正確的彈出當前被點選的li索引 -->
<ul id="testUL">
<li> index = 0</li>
<li> index = 1</li>
<li> index = 2</li>
<li> index = 3</li></ul>
JS:
<script type="text/javascript">
var nodes = document.getElementsByTagName("li");
for(i = 0;i<nodes.length;i+= 1){
nodes[i].onclick = (function(i){
return function() {
console.log(i);
} //不用閉包的話,值每次都是4 })(i);
}</script>
然後我們看看下面的一段程式碼,這是對閉包作用的非常直白的描述:
function say667() {// Local variable that ends up within closure
var num = 666;
var sayAlert = function() {
alert(num);
}
num++;
return sayAlert;
}var sayAlert = say667();
sayAlert()//執行結果應該彈出的667
執行say667()後,say667()閉包內部變數會存在,而閉包內部函式的內部變數不會存在
使得Javascript的垃圾回收機制GC不會收回say667()所佔用的資源
因為say667()的內部函式的執行需要依賴say667()中的變數
- javascript 程式碼中的"use strict";是什麼意思 ? 使用它區別是什麼?
除了正常執行模式,ECMAscript 5添加了第二種執行模式:"嚴格模式"(strict mode)。顧名思義,這種模式使得Javascript在更嚴格的條件下執行。
為什麼用嚴格模式
- 消除Javascript語法的一些不合理、不嚴謹之處,減少一些怪異行為;
- 消除程式碼執行的一些不安全之處,保證程式碼執行的安全;
- 提高編譯器效率,增加執行速度;
- 為未來新版本的Javascript做好鋪墊。
"嚴格模式"體現了Javascript更合理、更安全、更嚴謹的發展方向,包括IE 10在內的主流瀏覽器,都已經支援它,許多大專案已經開始全面擁抱它。
另一方面,同樣的程式碼,在"嚴格模式"中,可能會有不一樣的執行結果;一些在"正常模式"下可以執行的語句,在"嚴格模式"下將不能執行。掌握這些內容,有助於更細緻深入地理解Javascript,讓你變成一個更好的程式設計師。
進入標誌
"use strict";
如何呼叫
(1)針對單個指令碼
<script>
"use strict";
console.log("這是嚴格模式。");
</script>
(2)針對單個函式
function strict(){
"use strict";
return "這是嚴格模式。";
}
function notStrict() {
return "這是正常模式。";
}
語法與行為改變
嚴格模式對Javascript的語法和行為,都做了一些改變。
5.1 全域性變數顯式宣告
在正常模式中,如果一個變數沒有宣告就賦值,預設是全域性變數。嚴格模式禁止這種用法,全域性變數必須顯式宣告。
"use strict";
v = 1; // 報錯,v未宣告
for(i = 0; i < 2; i++) { // 報錯,i未宣告
}
因此,嚴格模式下,變數都必須先用var命令宣告,然後再使用。 禁止this關鍵字指向全域性物件
function f(){
return !this;
}
// 返回false,因為"this"指向全域性物件,"!this"就是false
function f(){
"use strict";
return !this;
}
// 返回true,因為嚴格模式下,this的值為undefined,所以"!this"為true。
因此,使用建構函式時,如果忘了加new,this不再指向全域性物件,而是報錯。
function f(){
"use strict";
this.a = 1;
};
f();// 報錯,this未定義
禁止刪除變數
嚴格模式下無法刪除變數。只有configurable設定為true的物件屬性,才能被刪除。
"use strict";
var x;
delete x; // 語法錯誤
var o = Object.create(null, {'x': {
value: 1,
configurable: true
}});
delete o.x; // 刪除成功
物件不能有重名的屬性
正常模式下,如果物件有多個重名屬性,最後賦值的那個屬性會覆蓋前面的值。嚴格模式下,這屬於語法錯誤。
"use strict";
var o = {
p: 1,
p: 2
}; // 語法錯誤
函式不能有重名的引數
正常模式下,如果函式有多個重名的引數,可以用arguments[i]讀取。嚴格模式下,這屬於語法錯誤。
"use strict";
function f(a, a, b) { // 語法錯誤
return ;
}
71、如何判斷一個物件是否屬於某個類?
javascript中檢測物件的型別的運算子有:typeof、constructor、instanceof。
typeof:typeof是一個一元運算子,返回結果是一個說明運算數型別的字串。如:"number","string","boolean","object","function","undefined"(可用於判斷變數是否存在)。 但 typeof 的能力有限,其對於Date、RegExp、Array型別返回的都是"object"。所以它只在區別物件和原始型別的時候才有用。要區一種物件型別和另一種物件型別,必須使用其他的方法。
instanceof 運算子:instanceof 運算子要求其左邊的運算數是一個物件,右邊的運算數是物件類的名字或建構函式。如果 object 是 class 或建構函式的例項,則 instanceof 運算子返回 true。如果 object 不是指定類或函式的例項,或者 object 為 null,則返回 false。instanceof方法可以判斷變數是否是陣列型別,但是隻限同一全域性環境之內,在一個頁面有多個iframe的情況下,instanceof失效。
constructor 屬性: JavaScript中,每個物件都有一個constructor屬性,它引用了初始化該物件的建構函式,常用於判斷未知物件的型別。如給定一個求知的值 通過typeof運算子來判斷它是原始的值還是物件。如果是物件,就可以使用constructor屬性來判斷其型別。
Object.prototype.toString.call():該方法是目前為止發現的判斷一個物件型別的最好的辦法。
72、Javascript中,有一個函式,執行時物件查詢時,永遠不會去查詢原型,這個函式是?
hasOwnProperty
73、[].forEach.call($$("*"),function(a){ a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16) })
能解釋一下這段程式碼的意思嗎?
(1)call:call(thisObj,arg1,arg2,arg3)
1 |
|
就是用$$('a')來替代[],
好 那麼到了第二個問題$$('a')是什麼意思
(2)$$('a')
你可以在自己的瀏覽器上面執行一下,就是頁面上所有的a標籤
然後再繼續
(3)function(a){}
無疑就是$$('a')組成的陣列要進行的回撥函數了
好我們再看裡面的東西
(4)~~
看在瀏覽器上面的執行
1 2 3 4 5 6 7 8 |
|
所以~~的作用就相當於parseInt
- js延遲載入的方式有哪些?
js的延遲載入有助與提高頁面的載入速度,以下是延遲載入的幾種方法:
(1)使用setTimeout延遲方法的載入時間
延遲載入js程式碼,給網頁載入留出更多時間
<script type="text/javascript" >
function A(){
$.post("/lord/login",{name:username,pwd:password},function(){
alert("Hello");
});
}
$(function (){
setTimeout('A()', 1000); //延遲1秒
})</script>
(2)讓js最後載入
例如引入外部js指令碼檔案時,如果放入html的head中,則頁面載入前該js指令碼就會被載入入頁面,而放入body中,則會按照頁面從上倒下的載入順序來執行javascript的程式碼~~~ 所以我們可以把js外部引入的檔案放到頁面底部,來讓js最後引入,從而加快頁面載入速度
(3)上述方法2也會偶爾讓你收到Google頁面速度測試工具的“延遲載入javascript”警告。所以這裡的解決方案將是來自Google幫助頁面的推薦方案。
//
這些程式碼應被放置在
</body>標籤前(接近HTML檔案底部)
<script type="text/javascript">
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "defer.js";
document.body.appendChild(element);
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;</script>
這段程式碼意思是等到整個文件載入完後,再載入外部檔案“defer.js”。
使用此段程式碼的步驟:
1).複製上面程式碼
2).貼上程式碼到HTML的標籤前 (靠近HTML檔案底部)
3).修改“defer.js”為你的外部JS檔名
4).確保你檔案路徑是正確的。例如:如果你僅輸入“defer.js”,那麼“defer.js”檔案一定與HTML檔案在同一資料夾下。
注意:這段程式碼直到文件載入完才會載入指定的外部js檔案。因此,不應該把那些頁面正常載入需要依賴的javascript程式碼放在這裡。而應該將JavaScript程式碼分成兩組。一組是因頁面需要而立即載入的javascript程式碼,另外一組是在頁面載入後進行操作的javascript程式碼(例如新增click事件或其他東西)。這些需等到頁面載入後再執行的JavaScript程式碼,應放在一個外部檔案,然後再引進來。
75、同步和非同步的區別?
同步:
同步的思想是:所有的操作都做完,才返回給使用者。這樣使用者線上等待的時間太長,給使用者一種卡死了的感覺(就是系統遷移中,點選了遷移,介面就不動了,但是程式還在執行,卡死了的感覺)。這種情況下,使用者不能關閉介面,如果關閉了,即遷移程式就中斷了。
非同步:
將使用者請求放入訊息佇列,並反饋給使用者,系統遷移程式已經啟動,你可以關閉瀏覽器了。然後程式再慢慢地去寫入資料庫去。這就是非同步。但是使用者沒有卡死的感覺,會告訴你,你的請求系統已經響應了。你可以關閉介面了。
同步,是所有的操作都做完,才返回給使用者結果。即寫完資料庫之後,在相應使用者,使用者體驗不好。
非同步,不用等所有操作等做完,就相應使用者請求。即先相應使用者請求,然後慢慢去寫資料庫,使用者體驗較好。
非同步操作例子:
為了避免短時間大量的資料庫操作,就使用快取機制,也就是訊息佇列。先將資料放入訊息佇列,然後再慢慢寫入資料庫。
引入訊息佇列機制,雖然可以保證使用者請求的快速響應,但是並沒有使得我資料遷移的時間變短(即80萬條資料寫入mysql需要1個小時,用了redis之後,還是需要1個小時,只是保證使用者的請求的快速響應。使用者輸入完http url請求之後,就可以把瀏覽器關閉了,幹別的去了。如果不用redis,瀏覽器不能關閉)。
同步就沒有任何價值了嗎?
銀行的轉賬功能。
76、頁面編碼和被請求的資源編碼如果不一致如何處理?
s編碼和頁面編碼不一致,導致提示變數未定義的解決方法 (2011-06-30 10:27:02)轉載▼
標籤: js跨域 變數未定義 js編碼 it 分類: JS
今天在測試專案的時候,由於是和其他站合作的,引用合作方的js檔案,
有個js函式呼叫,呼叫時會使用包含合作方js裡的變數,
可是竟然不相容ie6、ie7、360等主流瀏覽器。那必須得解決是吧。
原本以為是跨域問題,如果是跨域問題,也應該提示沒許可權,可是沒提示。
提示的是某某變數未定義,我就百度了。 沒找到我想要的答案,
靈機一動想到是不是編碼問題 。於是在js後加了 charset="utf-8" 這個 。
發現還真好了。 。 繞了好些圈子 。 這次記下了。避免下次再遇到類似的狀況。
比如:http://www.yyy.com/a.html 中嵌入了一個http://www.xxx.com/test.js
a.html 的編碼是gbk或gb2312的。 而引入的js編碼為utf-8的 ,那就需要在引入的時候
<script src="http://www.xxx.com/test.js" charset="utf-8"></script>
同理,如果你的頁面是utf-8的,引入的js是gbk的,那麼就需要加上charset="gbk".
77、AMD(Modules/Asynchronous-Definition)、CMD(Common Module Definition)規範區別?
AMD
AMD規範其實只有一個主要介面 define(id,dependencies,factory),它要在宣告模組的時候指定所有的依賴dependencies,並且還要當做形參傳到factory中,對於依賴的模組提前執行,依賴前置
[javascript] view plain copy
- define("module", ["dep1", "dep2"], function(d1, d2) {
- return someExportedValue;
- });
- require(["module", "../file"], function(module, file) { /* ... */ });
優點:
適合在瀏覽器環境非同步載入
並行載入多個模組
缺點:
提高開發成本,程式碼閱讀和書寫比較困難
不符合通用的模組思維方式,是一種妥協的實現
CMD
CMD規範和AMD相似,儘量保持簡單,並且與CommonJS和NodeJS的Modules規範保持了很大的相容性。
[javascript] view plain copy
- define(function(require, exports, module) {
- var $ = require('jquery');
- var Spinning = require('./spinning');
- exports.doSomething = ...
- module.exports = ...
- })
優點:
依賴就近,延遲執行
很容易在node中執行
缺點:
依賴SPM打包,模組的載入邏輯偏重
78、談一談你對ECMAScript6的瞭解?
ES6 包含了很多新的語言功能,且這些語言功能使得 JS 更加強大更富有表現力。
ECMAScript 的範圍是什麼?
JavaScript 程式語言是由 ECMAScript 名下的 ECMA 進行標準化制定的( ECMA 是和 W3C 一樣的標準化組織 )。除此之外,ECMAScript 可如下定義:
語法-解析規則,關鍵字,語句,宣告,操作等等。
型別-布林型,數字,字串,物件等等。
原型和繼承。
內建物件和函式的標準庫 - JSON ,數學( Math ), 陣列方法( Array methods ),物件內省的方法( Object introspection methods )等等。
其沒有定義與 HTML 、CSS 或者 Web API 互動的內容,比如 DOM ( 文件物件模型 )。那些都是在單獨的標準中定義的。 ECMAScript 不僅在瀏覽器環境中的涵蓋了 JS 的所有方面,其在非瀏覽器環境中也涵蓋了 JS ,例如 node.js 。
新的標準
上週, ECMAScript 語言規範的最終草案,第 6 版,被提交給 ECMA 大會進行審查。這意味著什麼呢?
這意味著這個夏天,對於核心的 JavaScript 程式語言,我們將有一個新的標準。
這是一個大新聞。新的 JS 語言不是每天都可能出現的。 上一個版本,ES5,可以追溯到 2009 年。從那時起,ES 標準委員會就一直致力於 ES6 的制定直至今日。
ES6 是語言的一次重大的升級。同時,你的 JS 程式碼也可以繼續工作。ES6 被設計為可以最大程度相容現有的程式碼。事實上,很多瀏覽器已經支援豐富的 ES6 的功能,同時實現工作也正在進行中。這就意味著你所有的 JS 程式碼已經可以在那些實現一些 ES6 功能的瀏覽器裡面執行!如果你到現在還沒有看到任何相容性問題,你可能永遠也不會碰到這些問題了。
計數到 6
ECMAScript 標準的先前的版本分別編號為 1,2,3 和 5。
第四版本發生了什麼?第 4 版的 ECMAScript 曾是在計劃之中的,並且事實上大量的工作也已經完成了。但由於它過於的繁瑣,其最終被廢棄了。 ( 例如,它在靜態型別系統中對泛型和型別推斷有一個複雜的選擇。)
ES4 是有爭議的。當標準委員會最終停止繼續制定時,該委員會成員同意出版一個相對溫和的 ES5 ,然後繼續工作以制定更多的有較大幅度改進的新功能。這個直接通過談判達成的協議被稱為“和諧(Harmony)”,這也是為什麼 ES5 規範包含這兩句話:
ECMAScript 是一個充滿活力的語言且其語言的演化還不完整。在未來的 ECMAScript 的版本中將有較大提升的技術的宣告。
這種說法也可以被看作是委員會給出的一個承諾。
兌現承諾
ES5 在 2009 年對語言進行了更新,其介紹了 Object.create( ), Object.defineProperty( ), getter 和 setter 方法,strict 模式和 JSON 物件。我已經使用了所有的這些功能,而且我喜歡 ES5 對語言做出的貢獻。但是, 這些功能中的任何一種都沒有對我寫 JS 程式碼的方式產生巨大的影響。對我來說其最重要的創新,很可能是新的陣列方法:.MAP,filter 等等。
然而,ES6 是決然不同的。它是多年和諧工作的產物。 同時,它是新的語言和庫功能的寶庫,其是迄今為止 JS 的最實質性的升級。 其新功能涵蓋面很廣,從那些很受歡迎的能帶來便利的功能(如箭頭的功能和簡單的字串插值),到能帶來頭腦風暴的概念(如代理和生成器)。
ES6 將改變你寫 JS 程式碼的方式。
本系列旨在向你展示 ES6 如何通過檢查其新功能來給JavaScript程式設計師提供新的寫程式碼體驗。
我們將以一個典型的“功能缺失”作為開始。“功能缺失”是我在過去的十年的時間內一直渴望能從 JavaScript 那看到的。所以,讓我們一起去探索 ES6 迭代器和新的 for-of 迴圈。
79、ECMAScript6 怎麼寫class麼,為什麼會出現class這種東西?
ES6 的 class 有優點也有缺點,整體說來,是利大於弊的,推薦使用。
缺點主要有:
(1)語法和語義難對上了,也就是說從書寫出來的程式碼是看不出來內部是通過原型實現相關功能點的。
(2)類的寫法有一定的限制性,不再像原型那麼靈活了。
優點主要有:
(1)語法更加緊湊,更加符合傳統面相物件的寫法了。
(2)使 IDE 、型別檢查器、程式碼風格檢查器等工具更方便地檢測程式碼語法,做靜態分析。
(3) ES6 的類可以繼承內建類,並使某些屬性和內建類有一樣的行為。比如可以繼承 Array ,並且子類的 length 屬性和 Array 的 length 屬性一樣會隨著元素個數的變化而自動變化。
(4)相容以前的程式碼。
(5)使初學者入門更快。
(6)不再需要第三方的繼承庫。
最後, ES6 的類只是一個基礎形式,後續 ECMAScript 版本還會繼續新增一些內容進去,比如 trait 、不可變例項等。
其實,從多人開發的大型專案來看,其中使用的大多數語言都包含了類這個元素,並且類在這些專案中還被廣泛使用。這就說明類有利於多人大型專案的開發。而 ES6 引入類,也表明了現在的 js 專案越來越複雜了,同時也為 js 在伺服器端舞臺上大放異彩奠定基礎。
80、documen.write和 innerHTML的區別?
(1).write是DOM方法,向文件寫入HTML表示式或JavaScript程式碼,可列出多個引數,引數被順序新增到文件中 ;innerHTML是DOM屬性,設定或返回呼叫元素開始結束標籤之間的HTML元素。
(2)兩者都可向頁面輸出內容,innerHTML比document.write更靈活。
當文件載入時呼叫document.write直接向頁面輸出內容,文件載入結束後呼叫document.write輸出內容會重寫整個頁面。通常按照兩種的方式使用 write() 方法:一是在使用該方在文件中輸出 HTML,二是在呼叫該方法的的視窗之外的視窗、框架中產生新文件(務必使用close關閉文件)。
在讀模式下,innerHTML屬性返回與呼叫元素的所有子節點對應的HTML標記,在寫模式下,innerHTML會根據指定的值建立新的DOM樹替換呼叫元素原先的所有子節點。
(3)兩者都可動態包含外部資源如JavaScript檔案
通過document.write插入<script>元素會自動執行其中的指令碼;
大多數瀏覽器中,通過innerHTML插入<script>元素並不會執行其中的指令碼。
81、JS 怎麼實現一個類。怎麼例項化這個類
嚴格的說,JavaScript 是基於物件的程式語言,而不是面向物件的程式語言。
在面向物件的程式語言中(如Java、C++、C#、PHP等),宣告一個類使用 class 關鍵字。
例如:
- public class Person{}
但是在JavaScript中,沒有宣告類的關鍵字,也沒有辦法對類的訪問許可權進行控制。
JavaScript 使用函式來定義類。
語法:
function className(){
// 具體操作
}
例如,定義一個Person類:
function Person() {
this.name=" 張三 "; // 定義一個屬性 name
this.sex=" 男 "; // 定義一個屬性 sex
this.say=function(){ // 定義一個方法 say()
document.write("嗨!大家好,我的名字是 " + this.name + " ,性別是 " + this.sex + "。");
}
}
說明:this 關鍵字是指當前的物件。
建立物件(類的例項化)
建立物件的過程也是類例項化的過程。
在JavaScript中,建立物件(即類的例項化)使用 new 關鍵字。
語法:
new className();
將上面的 Person 類例項化:
var zhangsan=new Person();
zhangsan.say();
執行程式碼,輸出如下內容:
嗨!大家好,我的名字是 張三 ,性別是 男 。
定義類時可以設定引數,建立物件時也可以傳遞相應的引數。
下面,我們將Person類重新定義:
function Person(name,sex) {
this.name=name; // 定義一個屬性 name
this.sex=sex; // 定義一個屬性 sex
this.say=function(){ // 定義一個方法 say()
document.write("嗨!大家好,我的名字是 " + this.name + " ,性別是 " + this.sex);
}
}
var zhangsan=new Person("小麗","女");
zhangsan.say();
執行程式碼,輸出如下內容:
嗨!大家好,我的名字是 小麗 ,性別是 女 。
- jquery中如何將陣列轉化為json字串,然後再轉化回來?
現代瀏覽器中提供了JSON.stringify()方法 將陣列,物件轉成json。
JSON.stringify 把一個物件轉換成json字串,
JSON.parse 把一個json字串解析成物件。
不支援的可以引入json2.js
$.fn.stringifyArray = function(array) {
return JSON.stringify(array)
}
$.fn.parseArray = function(array) {
return JSON.parse(array)
}
然後呼叫:
$("").stringifyArray(array)
83、jQuery 的屬性拷貝(extend)的實現原理是什麼,如何實現深拷貝?
語法:jQuery.extend( [deep ], target, object1 [, objectN ] )
描述: 將兩個或更多物件的內容合併到第一個物件。
關於$.extend()的用法網上有很多文章,在這裡指向寫寫對深淺拷貝的理解
深淺拷貝對應的引數就是[deep],是可選的,為true或false。預設情況是false(淺拷貝),並且false是不能夠顯示的寫出來的。如果想寫,只能寫true(深拷貝)~~
什麼是深、淺拷貝呢?先講定義,再舉例子
在預設情況下,通過$.extend()
合併操作不是遞迴的(淺拷貝);如果第一個物件的屬性本身是一個物件或陣列,那麼它將完全用第二個物件相同的key重寫一個屬性。這些值不會被合併。然而,如果將 true
作為該函式的第一個引數,那麼會在物件上進行遞迴的合併(深拷貝)。
淺拷貝(false 預設):如果第二個引數物件有的屬性第一個引數物件也有,那麼不會進行相同引數內部的比較,直接將第一個物件的相同引數覆蓋。
深拷貝(true):如果第二個引數物件有的屬性第一個引數物件也有,還要繼續在這個相同的引數向下一層找,比較相同引數的物件中是否還有不一樣的屬性,如果有,將其繼承到第一個物件,如果沒有,則覆蓋。
var object1 = {
apple: 0,
banana: {
weight: 52,
price: 100
},
cherry: 97
};var object2 = {
banana: {
price: 200
},
durian: 100
};
//預設情況淺拷貝
//object1--->{"apple":0,"banana":{"price":200},"cherry":97,"durian":100}
//object2的banner覆蓋了object1的banner,但是weight屬性未被繼承
//$.extend(object1, object2);
//深拷貝
//object1--->{"apple":0,"banana":{"weight":52,"price":200},"cherry":97,"durian":100}
//object2的banner覆蓋了object1的banner,但是weight屬性也被繼承了呦
$.extend(true,object1, object2);
console.log('object1--->'+JSON.stringify(object1));
84、jquery.extend 與 jquery.fn.extend的區別?
(1). jQuery.extend(object);
它是為jQuery類新增類方法,可以理解為新增靜態方法。如:
a.jQuery.extend({
min: function(a, b) { return a < b ? a : b; },
max: function(a, b) { return a > b ? a : b; }
});
jQuery.min(2,3); // 2
jQuery.max(4,5); // 5
b. jQuery.extend(target, object1, [objectN])用一個或多個其他物件來擴充套件一個物件,返回被擴充套件的物件。var settings = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
jQuery.extend(settings, options);
結果:settings == { validate: true, limit: 5, name: "bar" }
(2). jQuery.fn.extend(object);
$.fn是什麼?
$.fn是指jQuery的名稱空間,fn上的成員(方法function及屬性property),會對jQuery例項每一個有效。
檢視jQuery程式碼,就不難發現。
jQuery.fn = jQuery.prototype = {
init: function( selector, context ) {//....
};
原來 jQuery.fn = jQuery.prototype.
所以,它是對jQuery.prototype進得擴充套件,就是為jQuery類新增“成員函式”。jQuery類的例項可以使用這個“成員函式”。
比如我們要開發一個外掛,做一個特殊的編輯框,當它被點選時,便alert 當前編輯框裡的內容。可以這麼做:
$.fn.extend({
doAlertWhileClick:function() {
$(this).click(function(){
alert($(this).val());
});
}
});
$("#input1").doAlertWhileCli