摘要:如果構(gòu)造函數(shù)竊取結(jié)合使用原型鏈或者寄生組合則可以解決這個(gè)問題惰性載入函數(shù)惰性載入表示函數(shù)執(zhí)行的分支僅會(huì)發(fā)生一次。當(dāng)?shù)诙握{(diào)用該函數(shù)時(shí),它會(huì)清除前一次的定時(shí)器并設(shè)置另一個(gè)。,用于注銷某個(gè)事件類型的事件處理程序。
高級(jí)技巧 高級(jí)函數(shù) 安全的類型檢測
typeof操作符在檢測數(shù)據(jù)類型時(shí),可能會(huì)得到不靠譜的結(jié)果
instanceof操作符在存在多個(gè)全局作用域,也就是頁面包含多個(gè)iframe的情況下,也會(huì)出現(xiàn)問題
在任何值上調(diào)用Object原生的toString()方法,都會(huì)返回一個(gè)[object NativeConstructorName]格式的字符串
原生數(shù)組的構(gòu)造函數(shù)名與全局作用域無關(guān),因此使用toString()就能保證返回一致的值
function isArray(value){ return Object.prototype.toString.call(value)=="[object Array]"; }
基于這一思路來測試某個(gè)值是不是原生函數(shù)或正則表達(dá)式
function isFunction(value){ return Object.prototype.toString.call(value)=="[object Function]"; } function isRegExp(value){ return Object.prototype.toString.call(value)=="[object RegExp]"; }作用域安全的構(gòu)造函數(shù)
作用域安全的構(gòu)造函數(shù)在進(jìn)行任何更改之前,首先確認(rèn)this對象是正確類型的實(shí)例,如果不是,那么會(huì)創(chuàng)建新的實(shí)例并返回
function Person(name, age, job){ if (this instanceof Person){ this.name = name; this.age = age; this.job = job; } else { return new Person(name, age, job); } } var person1 = Person("Nicholas", 29, "Software Engineer"); alert(window.name); //"" alert(person1.name); //"Nicholas" var person2 = new Person("Shelby", 34, "Ergonomist"); alert(person2.name); //"Shelby
使用構(gòu)造函數(shù)竊取模式的繼承且不適用原型鏈,這個(gè)繼承可能被破壞
function Polygon(sides){ if (this instanceof Polygon) { this.sides = sides; this.getArea = function(){ return 0; }; } else { return new Polygon(sides); } } function Rectangle(width, height){ Polygon.call(this, 2); this.width = width; this.height = height; this.getArea = function(){ return this.width * this.height; }; } var rect = new Rectangle(5, 10); alert(rect.sides); //undefined
上面的代碼中,Polygon構(gòu)造函數(shù)是作用域安全的,然而Rectangle構(gòu)造函數(shù)則不是。如果構(gòu)造函數(shù)竊取結(jié)合使用原型鏈或者寄生組合則可以解決這個(gè)問題
function Polygon(sides){ if (this instanceof Polygon) { this.sides = sides; this.getArea = function(){ return 0; }; } else { return new Polygon(sides); } } function Rectangle(width, height){ Polygon.call(this, 2); this.width = width; this.height = height; this.getArea = function(){ return this.width * this.height; }; } Rectangle.prototype = new Polygon(); var rect = new Rectangle(5, 10); alert(rect.sides); //2惰性載入函數(shù)
惰性載入表示函數(shù)執(zhí)行的分支僅會(huì)發(fā)生一次。
第一種實(shí)現(xiàn)惰性載入的方法,在函數(shù)被調(diào)用時(shí)再處理函數(shù)。在第一次調(diào)用的過程中,該函數(shù)會(huì)覆蓋為另一個(gè)按何時(shí)方式執(zhí)行的函數(shù),這樣任何對原函數(shù)的調(diào)用都不用再經(jīng)過執(zhí)行的分支了
function createXHR(){ if (typeof XMLHttpRequest != "undefined"){ createXHR = function(){ return new XMLHttpRequest(); }; } else if (typeof ActiveXObject != "undefined"){ createXHR = function(){ if (typeof arguments.callee.activeXString != "string"){ var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"], i, len; for (i=0,len=versions.length; i < len; i++){ try { new ActiveXObject(versions[i]); arguments.callee.activeXString = versions[i]; break; } catch (ex){ //skip } } } return new ActiveXObject(arguments.callee.activeXString); }; } else { createXHR = function(){ throw new Error("No XHR object available."); }; } return createXHR(); }
第二種實(shí)現(xiàn)惰性載入的方式是在聲明函數(shù)時(shí)就指定適當(dāng)?shù)暮瘮?shù),這樣,第一次調(diào)用函數(shù)時(shí)就不會(huì)喪失性能了,而在代碼首次加載的時(shí)候回?fù)p失一點(diǎn)性能
var createXHR = (function(){ if (typeof XMLHttpRequest != "undefined"){ return function(){ return new XMLHttpRequest(); }; } else if (typeof ActiveXObject != "undefined"){ return function(){ if (typeof arguments.callee.activeXString != "string"){ var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"], i, len; for (i=0,len=versions.length; i < len; i++){ try { new ActiveXObject(versions[i]); arguments.callee.activeXString = versions[i]; break; } catch (ex){ //skip } } } return new ActiveXObject(arguments.callee.activeXString); }; } else { return function(){ throw new Error("No XHR object available."); }; } })();函數(shù)綁定
一個(gè)簡單的bind()函數(shù)接受一個(gè)函數(shù)和一個(gè)環(huán)境,并返回一個(gè)在給定環(huán)境中調(diào)用給定函數(shù)的函數(shù),并且將所有參數(shù)原封不動(dòng)傳遞過去
function bind(fn, context){ return function(){ return fn.apply(context, arguments); }; }
當(dāng)調(diào)用返回的函數(shù)時(shí),它會(huì)在給定環(huán)境中執(zhí)行被傳入的函數(shù)并給出所有參數(shù)
var handler = { message: "Event handled", handleClick: function(event){ alert(this.message); } }; var btn = document.getElementById("my-btn"); EventUtil.addHandler(btn, "click", bind(handler.handleClick, handler))
ECMAScript5為所有函數(shù)定義了一個(gè)原生的bind()方法,進(jìn)一步簡單了操作,不用再自己定義bind()函數(shù)了,而是可以直接在函數(shù)上調(diào)用這個(gè)方法
var handler = { message: "Event handled", handleClick: function(event){ alert(this.message + ":" + event.type); } }; var btn = document.getElementById("my-btn"); EventUtil.addHandler(btn, "click", handler.handleClick.bind(handler));函數(shù)的柯里化
用于創(chuàng)建已經(jīng)設(shè)置好了一個(gè)或者多個(gè)參數(shù)的函數(shù)。函數(shù)柯里化的基本方法和函數(shù)綁定是一樣的。使用一個(gè)閉包返回一個(gè)函數(shù),兩者的區(qū)別在于,當(dāng)函數(shù)被調(diào)用時(shí),返回的函數(shù)還需要設(shè)置一些傳入的參數(shù)
柯里化函數(shù)通常由一下步驟動(dòng)態(tài)創(chuàng)建:調(diào)用另一個(gè)函數(shù)并為它傳入要柯里化的函數(shù)和必要參數(shù)
function curry(fn){ var args = Array.prototype.slice.call(arguments, 1); return function(){ var innerArgs = Array.prototype.slice.call(arguments); var finalArgs = args.concat(innerArgs); return fn.apply(null, finalArgs); }; }
ECMAScript5的bind()方法也實(shí)現(xiàn)函數(shù)柯里化,只要在this的值之后再傳入另一個(gè)參數(shù)即可
var handler = { message: "Event handled", handleClick: function(name, event){ alert(this.message + ":" + name + ":" + event.type); } }; var btn = document.getElementById("my-btn"); EventUtil.addHandler(btn, "click", handler.handleClick.bind(handler, "my-btn"));防篡改對象 不可擴(kuò)展對象
默認(rèn)情況下,所有對象都是可以擴(kuò)展的,也就是說,任何時(shí)候都可以向?qū)ο笾刑砑訉傩院头椒?/p>
Object.preventExtensions()方法可以改變這個(gè)行為,不能再給對象添加屬性和方法
var person={name:"Nicholas"}; Object.preventExtensions(person); person.age=29; alert(person.age);//undefined
Object.isExtensible()方法還可以確定對象是否可以擴(kuò)展
var person={name:"Nicholas"}; alert(Object.isExtensible(person));//true Object.preventExtensions(person); alert(Object.isExtensible(person));//true密封的對象
封閉對象不可擴(kuò)展,而且已有成員[Configurable]特性將被設(shè)置為false,這就意味著不能刪除屬性和方法,因?yàn)椴荒苁褂肙bject.defineProperty()把數(shù)據(jù)屬性修改為訪問器屬性
var person = { name: "Nicholas" }; Object.seal(person); person.age = 29; alert(person.age); //undefined delete person.name; alert(person.name); //"Nicholas"
Object.isSealed()方法可以確定對象是否被密封了,因?yàn)楸幻芊獾膶ο蟛豢蓴U(kuò)展,所以用Object.isExtensible()檢測密封的對象也會(huì)返回false
var person = { name: "Nicholas" }; alert(Object.isExtensible(person)); //true alert(Object.isSealed(person)); //false Object.seal(person); alert(Object.isExtensible(person)); //false alert(Object.isSealed(person)); //true凍結(jié)的對象
凍結(jié)的對象既不可擴(kuò)展又是密封的,而且對象數(shù)據(jù)屬性的[Writable]特性會(huì)被設(shè)置為false,如果定義[Set]函數(shù),訪問器屬性仍然是可寫的。ECMAScript5丁意思的Object.freeze()方法可以用來凍結(jié)對象
var person = { name: "Nicholas" }; Object.freeze(person); person.age = 29; alert(person.age); //undefined delete person.name; alert(person.name); //"Nicholas" person.name = "Greg"; alert(person.name); //"Nicholas"
Object.isFrozen()方法用于檢測凍結(jié)對象,因?yàn)閮鼋Y(jié)對象既是密封的又是不可擴(kuò)展的,所以O(shè)bject.isExtensible()和Object.isSealed()檢測凍結(jié)對象將分別返回false和true
var person = { name: "Nicholas" }; alert(Object.isExtensible(person)); //true alert(Object.isSealed(person)); //false alert(Object.isFrozen(person)); //false Object.freeze(person); alert(Object.isExtensible(person)); //false alert(Object.isSealed(person)); //true alert(Object.isFrozen(person)); //true高級(jí)定時(shí)器 重復(fù)的定時(shí)器
使用setInterval()創(chuàng)建的定時(shí)器確保了定時(shí)器代碼規(guī)則地插入隊(duì)列中
使用setInterval()時(shí),僅當(dāng)沒有該定時(shí)器的任何其他代碼實(shí)現(xiàn)時(shí),才將定時(shí)器代碼添加到隊(duì)列中,這確保了定時(shí)器加入到隊(duì)列中的最小時(shí)間間隔為指定間隔
重復(fù)定時(shí)器有兩個(gè)問題:某些間隔會(huì)被跳過;多個(gè)定時(shí)器的代碼執(zhí)行之間的間隔可能會(huì)比預(yù)期小
為了避免setInterval()的重復(fù)定時(shí)器的兩個(gè)問題,使用鏈?zhǔn)絪etTimeout()調(diào)用
setTimeout(function(){ //處理中 setTimeout(arguments.callee, interval); }, interval);
這個(gè)模式主要用于重復(fù)定時(shí)器
setTimeout(function(){ var div = document.getElementById("myDiv"); left = parseInt(div.style.left) + 5; div.style.left = left + "px"; if (left < 200){ setTimeout(arguments.callee, 50); } }, 50)Yielding Processes
腳本長時(shí)間運(yùn)行的問題通常是由兩個(gè)原因之一造成的:過長的、過深嵌套的函數(shù)調(diào)用或者是進(jìn)行大量處理的循環(huán)
兩個(gè)重要問題:該處理是否必須同步完成;數(shù)據(jù)是否必須按順序完成
如果兩個(gè)問題回答都是否,可以使用定時(shí)器分隔這個(gè)循環(huán),即數(shù)組分塊技術(shù)
小塊小塊地處理數(shù)組,通常每次一小塊,基本的思路是為要處理的項(xiàng)目創(chuàng)建一個(gè)隊(duì)列,然后使用定時(shí)器取出下一個(gè)要處理的項(xiàng)目進(jìn)行處理,接著再設(shè)置另一個(gè)定時(shí)器
setTimeout(function(){ //取出下一個(gè)條目并處理 var item = array.shift(); process(item); //若還有條目,再設(shè)置另一個(gè)定時(shí)器 if(array.length > 0){ setTimeout(arguments.callee, 100); } }, 100);
數(shù)組分塊模式中,array變量本質(zhì)上就是一個(gè)列表,包含了要處理的項(xiàng)目。使用shift()方法獲取隊(duì)列中要處理的項(xiàng)目,然后將其傳遞給某個(gè)函數(shù)。如果在隊(duì)列中還有其他項(xiàng)目,則設(shè)置另一個(gè)定時(shí)器,并通過arguments.callee調(diào)用同一個(gè)匿名函數(shù),要實(shí)現(xiàn)數(shù)組分塊非常簡單,可以使用下面的函數(shù)
function chunk(array, process, context){ setTimeout(function(){ var item = array.shift(); process.call(context, item); if (array.length > 0){ setTimeout(arguments.callee, 100); } }, 100); }
chunk()方法接收三個(gè)參數(shù):要處理的項(xiàng)目的數(shù)組,用于處理項(xiàng)目的函數(shù),以及可選的運(yùn)行該函數(shù)的環(huán)境
var data = [12,123,1234,453,436,23,23,5,4123,45,346,5634,2234,345,342]; function printValue(item){ var div = document.getElementById("myDiv"); div.innerHTML += item + "函數(shù)節(jié)流
"; } chunk(data, printValue);
函數(shù)節(jié)流背后的基本思想是指,某些代碼不可以在沒有間斷的情況連續(xù)重復(fù)執(zhí)行。第一次調(diào)用函數(shù),創(chuàng)建一個(gè)定時(shí)器,在指定的時(shí)間間隔之后運(yùn)行代碼。當(dāng)?shù)诙握{(diào)用該函數(shù)時(shí),它會(huì)清除前一次的定時(shí)器并設(shè)置另一個(gè)。如果前一個(gè)定時(shí)器已經(jīng)執(zhí)行過了,這個(gè)操作就沒有任何意義。然而,如果前一個(gè)定時(shí)器尚未執(zhí)行,其實(shí)就是將其替換為一個(gè)新的定時(shí)器。目的是只有在執(zhí)行函數(shù)的請求停止了一段時(shí)間之后才執(zhí)行。
var processor = { timeoutId: null, //實(shí)際進(jìn)行處理的方法 performProcessing: function(){ //實(shí)際執(zhí)行的代碼 }, //初始處理調(diào)用的方法 process: function(){ clearTimeout(this.timeoutId); var that = this; this.timeoutId = setTimeout(function(){ that.performProcessing(); }, 100); } }; //嘗試開始執(zhí)行 processor.process();自定義事件
觀察者模式由兩類對象組成:主體和觀察者。主體負(fù)責(zé)發(fā)布事件,同時(shí)觀察者通過訂閱這些事件來觀察該主體
自定義事件背后的概念是創(chuàng)建一個(gè)管理事件的對象,讓其他對象監(jiān)聽事件
function EventTarget(){ this.handlers = {}; } EventTarget.prototype = { constructor: EventTarget, addHandler: function(type, handler){ if (typeof this.handlers[type] == "undefined"){ this.handlers[type] = []; } this.handlers[type].push(handler); }, fire: function(event){ if (!event.target){ event.target = this; } if (this.handlers[event.type] instanceof Array){ var handlers = this.handlers[event.type]; for (var i=0, len=handlers.length; i < len; i++){ handlers[i](event); } } }, removeHandler: function(type, handler){ if (this.handlers[type] instanceof Array){ var handlers = this.handlers[type]; for (var i=0, len=handlers.length; i < len; i++){ if (handlers[i] === handler){ break; } } handlers.splice(i, 1); } } };
EventTarget類型有一個(gè)多帶帶的屬性handlers ,用于儲(chǔ)存事件處理程序。
還有三個(gè)方法:
addHandler() ,用于注冊給定類型事件的事件處理程序
addHandler() 方法接受兩個(gè)參數(shù):事件類型和用于處理該事件的函數(shù)。當(dāng)調(diào)用該方法時(shí),會(huì)進(jìn)行一次檢查,看看 handlers 屬性中是否已經(jīng)存在一個(gè)針對該事件類型的數(shù)組;如果沒有,則創(chuàng)建一個(gè)新的。然后使用 push() 將該處理程序添加到數(shù)組的末尾。
fire() ,用于觸發(fā)一個(gè)事件
如果要觸發(fā)一個(gè)事件,要調(diào)用 fire() 函數(shù)。該方法接受一個(gè)多帶帶的參數(shù),是一個(gè)至少包含 type屬性的對象。 fire() 方法先給 event 對象設(shè)置一個(gè) target 屬性,如果它尚未被指定的話。然后它就查找對應(yīng)該事件類型的一組處理程序,調(diào)用各個(gè)函數(shù),并給出 event 對象。
removeHandler() ,用于注銷某個(gè)事件類型的事件處理程序。
removeHandler() 方法是 addHandler() 的輔助,它們接受的參數(shù)一樣:事件的類型和事件處理程序。這個(gè)方法搜索事件處理程序的數(shù)組找到要?jiǎng)h除的處理程序的位置。如果找到了,則使用 break操作符退出 for 循環(huán)。然后使用 splice() 方法將該項(xiàng)目從數(shù)組中刪除。
function handleMessage(event){ alert("Message received: " + event.message); } //創(chuàng)建一個(gè)新對象 var target = new EventTarget(); //添加一個(gè)事件處理程序 target.addHandler("message", handleMessage); //觸發(fā)事件 target.fire({ type: "message", message: "Hello world!"}); //刪除事件處理程序 target.removeHandler("message", handleMessage); //再次,應(yīng)沒有處理程序 target.fire({ type: "message", message: "Hello world!"});拖放
基本實(shí)現(xiàn)過程
var DragDrop = function(){ var dragging = null; function handleEvent(event){ //獲取事件和目標(biāo) event = EventUtil.getEvent(event); var target = EventUtil.getTarget(event); //確定事件類型 switch(event.type){ case "mousedown": if (target.className.indexOf("draggable") > -1){ dragging = target; } break; case "mousemove": if (dragging !== null){ //指定位置 dragging.style.left = event.clientX + "px"; dragging.style.top = event.clientY + "px"; } break; case "mouseup": dragging = null; break; } }; //公共接口 return { enable: function(){ EventUtil.addHandler(document, "mousedown", handleEvent); EventUtil.addHandler(document, "mousemove", handleEvent); EventUtil.addHandler(document, "mouseup", handleEvent); }, disable: function(){ EventUtil.removeHandler(document, "mousedown", handleEvent); EventUtil.removeHandler(document, "mousemove", handleEvent); EventUtil.removeHandler(document, "mouseup", handleEvent); } } }();修繕拖動(dòng)功能
為防止出現(xiàn)上圖情況。計(jì)算元素左上角和指針位置之間的差值。這個(gè)差值應(yīng)該在 mousedown 事件發(fā)生的時(shí)候確定,并且一直保持,直到 mouseup 事件發(fā)生。通過將 event的 clientX 和 clientY 屬性與該元素的 offsetLeft 和 offsetTop 屬性進(jìn)行比較,就可以算出水平方向和垂直方向上需要多少空間
var DragDrop = function(){ var dragging = null; diffX = 0; diffY = 0; function handleEvent(event){ //獲取事件和目標(biāo) event = EventUtil.getEvent(event); var target = EventUtil.getTarget(event); //確定事件類型 switch(event.type){ case "mousedown": if (target.className.indexOf("draggable") > -1){ dragging = target; diffX = event.clientX - target.offsetLeft; diffY = event.clientY - target.offsetTop; } break; case "mousemove": if (dragging !== null){ //指定位置 dragging.style.left = (event.clientX - diffX) + "px"; dragging.style.top = (event.clientY - diffY) + "px"; } break; case "mouseup": dragging = null; break; } }; //公共接口 return { enable: function(){ EventUtil.addHandler(document, "mousedown", handleEvent); EventUtil.addHandler(document, "mousemove", handleEvent); EventUtil.addHandler(document, "mouseup", handleEvent); }, disable: function(){ EventUtil.removeHandler(document, "mousedown", handleEvent); EventUtil.removeHandler(document, "mousemove", handleEvent); EventUtil.removeHandler(document, "mouseup", handleEvent); } } }()添加自定義事件
var DragDrop = function(){ var dragdrop = new EventTarget(), dragging = null, diffX = 0, diffY = 0; function handleEvent(event){ //獲取事件和對象 event = EventUtil.getEvent(event); var target = EventUtil.getTarget(event); //確定事件類型 switch(event.type){ case "mousedown": if (target.className.indexOf("draggable") > -1){ dragging = target; diffX = event.clientX - target.offsetLeft; diffY = event.clientY - target.offsetTop; dragdrop.fire({type:"dragstart", target: dragging, x: event.clientX, y: event.clientY}); } break; case "mousemove": if (dragging !== null){ //指定位置 dragging.style.left = (event.clientX - diffX) + "px"; dragging.style.top = (event.clientY - diffY) + "px"; // 觸發(fā)自定義事件 dragdrop.fire({type:"drag", target: dragging, x: event.clientX, y: event.clientY}); } break; case "mouseup": dragdrop.fire({type:"dragend", target: dragging, x: event.clientX, y: event.clientY}); dragging = null; break; } }; //公共接口 dragdrop.enable = function(){ EventUtil.addHandler(document, "mousedown", handleEvent); EventUtil.addHandler(document, "mousemove", handleEvent); EventUtil.addHandler(document, "mouseup", handleEvent); }; dragdrop.disable = function(){ EventUtil.removeHandler(document, "mousedown", handleEvent); EventUtil.removeHandler(document, "mousemove", handleEvent); EventUtil.removeHandler(document, "mouseup", handleEvent); }; return dragdrop; }();
這段代碼定義了三個(gè)事件: dragstart 、 drag 和 dragend 。它們都將被拖動(dòng)的元素設(shè)置為了 target ,并給出了 x 和 y 屬性來表示當(dāng)前的位置。它們觸發(fā)于 dragdrop 對象上,之后在返回對象前給對象增加 enable() 和 disable() 方法。這些模塊模式中的細(xì)小更改令 DragDrop 對象支持了事件
DragDrop.addHandler("dragstart", function(event){ var status = document.getElementById("status"); status.innerHTML = "Started dragging " + event.target.id; }); DragDrop.addHandler("drag", function(event){ var status = document.getElementById("status"); status.innerHTML += "
Dragged " + event.target.id + " to (" + event.x + "," + event.y + ")"; }); DragDrop.addHandler("dragend", function(event){ var status = document.getElementById("status"); status.innerHTML += "
Dropped " + event.target.id + " at (" + event.x + "," + event.y + ")"; });
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/98189.html
摘要:基本概念語法區(qū)分大小寫,中的一切變量函數(shù)名和操作符都區(qū)分大小寫。要將一個(gè)值轉(zhuǎn)換成對應(yīng)的值,可以調(diào)用類型包括整數(shù)和浮點(diǎn)數(shù)值,基本數(shù)值字面量格式是十進(jìn)制整數(shù),除了十進(jìn)制外還有八進(jìn)制十六進(jìn)制。八進(jìn)制第一位必須是,十六進(jìn)制第一位必須是。 基本概念 語法 區(qū)分大小寫,ECMAScript中的一切(變量、函數(shù)名和操作符)都區(qū)分大小寫。函數(shù)名不能使用typeof,因?yàn)樗且粋€(gè)關(guān)鍵字,但typeOf...
摘要:當(dāng)代碼在一個(gè)環(huán)境中執(zhí)行時(shí),會(huì)創(chuàng)建變量對象的一個(gè)作用域鏈。作用域鏈的用途,是保證對執(zhí)行環(huán)境有權(quán)訪問的所有變量和函數(shù)的有序訪問。這樣,一直延續(xù)到全局執(zhí)行環(huán)境全局執(zhí)行環(huán)境的變量對象始終都是作用域鏈中的最后一個(gè)對象。 變量、作用域和內(nèi)存問題 基本類型和引用類型的值 基本類型值指的是簡單的數(shù)據(jù)段,而引用類型值值那些可能由多個(gè)值構(gòu)成的對象。 定義基本類型值的引用和引用類型值的方法是類似的,創(chuàng)建...
摘要:能力檢測無法精確地檢測特定的瀏覽器和版本。用戶代理檢測通過檢測用戶代理字符串來識(shí)別瀏覽器。用戶代理檢測需要特殊的技巧,特別是要注意會(huì)隱瞞其用戶代理字符串的情況。 客戶端檢測 能力檢測 能力檢測的目的不是識(shí)別特定的瀏覽器,而是識(shí)別瀏覽器的能力,采用這種方式不必顧忌特定的瀏覽器,只要確定瀏覽器支持的特定的能力,就能給出解決方案,檢測基本模式 if(object.propertyInQu...
摘要:對象的核心對象是,它表示瀏覽器的一個(gè)實(shí)例。而和則表示該容器中頁面視圖區(qū)的大小。在中,與返回相同的值,即視口大小而非瀏覽器窗口大小。第三個(gè)參數(shù)是一個(gè)逗號(hào)分隔的設(shè)置字符串,表示在新窗口中都顯示哪些特性。這應(yīng)該是用戶打開窗口后的第一個(gè)頁面 BOM window對象 BOM的核心對象是window,它表示瀏覽器的一個(gè)實(shí)例。在瀏覽器中,window對象有雙重角色,它既是通過JavaScript訪...
摘要:匿名函數(shù)可以用來模仿塊級(jí)作用域來避免這個(gè)問題這里是塊級(jí)作用域代碼定義并立即調(diào)用了一個(gè)匿名函數(shù),將函數(shù)聲明包含在一對圓括號(hào)中,表示它實(shí)際上是一個(gè)函數(shù)表達(dá)式,而緊隨其后的另一對圓括號(hào)會(huì)立即調(diào)用這個(gè)函數(shù)。 函數(shù)表達(dá)式 遞歸 遞歸函數(shù)是在一個(gè)函數(shù)通過名字調(diào)用自身的情況下構(gòu)成的 function factrial(num){ if(num
閱讀 1025·2021-11-22 13:52
閱讀 936·2019-08-30 15:44
閱讀 580·2019-08-30 15:43
閱讀 2436·2019-08-30 12:52
閱讀 3484·2019-08-29 16:16
閱讀 645·2019-08-29 13:05
閱讀 2951·2019-08-26 18:36
閱讀 2006·2019-08-26 13:46