-
如何給javascript物件動態建立動態key
// ES2015 var key = 'DYNAMIC_KEY', obj = { [key]: 'ES6!' }; console.log(obj); // > { 'DYNAMIC_KEY': 'ES6!' } // NON ES2015 var obj = []; obj[0] = "hello world"; obj["something"] = 5000; var objJSON = JSON.stringify(obj);
-
數字化的Date
js中,Date是內建的一種資料型別,雖然直接輸出的date格式適合人們閱讀,但是對於機器程式來說卻有些不方便:
var now=new Date(); console.log(now);//Wed Nov 25 2015 22:02:17 GMT+0800 (中國標準時間)
怎麼轉換為便於js程式來操作的形式呢?很簡單隻要在new關鍵字前面加上一個+即可:
var now=+new Date(); console.log(now);//1448460291345
javascript Errors: try{}catch(){}的重要性
在JS APP中,對於一些很有可能會出錯的程式碼,強烈建議使用try{}catch(){}的方式來呼叫,否則會出現一個錯誤就導致app crash的問題。相信crash並不是你想要的狀態,你可能希望出錯沒有關係啊,下次出錯的條件解除了,我們希望程式能夠繼續執行,這就必須使用try catch的模式來寫可能出錯的程式碼,允許出錯
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
try { foo.bar(); } catch (e) { if (e instanceof EvalError) { alert(e.name + ': ' + e.message); } else if (e instanceof RangeError) { alert(e.name + ': ' + e.message); } else if (e instanceof InternalError) { alert(e.name + ': ' + e.message); }else if (e instanceof ReferenceError) { alert(e.name + ': ' + e.message); }else if (e instanceof SyntaxError) { alert(e.name + ': ' + e.message); }else if (e instanceof TypeError) { alert(e.name + ': ' + e.message); }else if (e instanceof URIError) { alert(e.name + ': ' + e.message); } // ... etc }
Javascript小數點問題
由於javascript使用浮點數來運算小數,而小數總歸會有一定的精確度,所以往往出現一些比較怪異的問題:
console.log(0.1+0.2);//0.30000000000000004 console.log((0.1+0.2).toFixed(2));//0.30 (0.1+0.2)==0.3 //false!!!! (0.1+0.2).toFixed(1)==0.3 //true!!!
(0.1+0.2).toFixed(2)===0.3 //flase!!! 原因是toFixed(2)呼叫後實際上返回的是"0.30"
在上面的程式碼,由於toFixed將返回一個字串,所以使用===來比較,則返回false;再看下面的程式碼:
function tax(price,percent){ return parseFloat((price*percent/100).toFixed(2)); } var myprice = 9; var taxpercent =70; var total = myprice+tax(myprice,taxpercent); console.log(total.toFixed(2)); //"15.30"
javascript hoisting
<!DOCTYPE html> <html> <body> <p id="demo"></p> <script> var x = 5; // Initialize x elem = document.getElementById("demo"); // Find an element elem.innerHTML = "x is " + x + " and y is " + y; // Display x and y==> x is 5 and y is undefined,雖然y是declared了(due to hoisting),但是卻沒有defination未定義 var y = 7; // Initialize y </script> </body> </html>
modula Pattern
var ARMORY =(function(){ var weaponList = [*list of weapon objects*]; var armorList = [*list of armor objects*]; var removeWeapon = function(){}; var replaceWeapon = function(){}; var removeArmor = function(){}; var replaceArmor = function(){}; return { makeWeaponRequest: function(){}; makeArmorRequest: function(){}; }; })(); ARMORY.makeWeaponRequest('Excalibur');
上面這段程式碼中,使用IIFE呼叫後返回一個global object ARMORY作為namespace,暴露兩個public函式公外部呼叫,內部的local data都已經被封裝起來,
通過ARMORY.makeWeaponRequest()函式呼叫,來通過private函式removeWeapon又去訪問namespace的local variable weapList,刪除相應武器資料後,可能返回一個weapon列表物件的copy到ARMORY.makeWeaponRequest的scope中去使用。
Import Globals into IIFE
在上面的module pattern中,如果需要訪問一個全域性變數,比如我們新增一個指示是否正在戰爭遊戲的flag,在makeWeaponRequest函式中,我們根據這個flag來做特定的動作,那麼可行的方法是將wartime這個flag作為IIFE的引數傳入:
var wartime = true; var ARMORY =(function(war){ var weaponList = [*list of weapon objects*]; var armorList = [*list of armor objects*]; var removeWeapon = function(){}; var replaceWeapon = function(){}; var removeArmor = function(){}; var replaceArmor = function(){}; return { makeWeaponRequest: function(){ if(war) //let civilians have weaponry }; makeArmorRequest: function(){}; }; })(wartime); ARMORY.makeWeaponRequest('Excalibur');
在上面這個pattern中,需要注意的是wartime作為引數傳入了IIFE雖然意味著IIFE中能夠方便的訪問到wartime的資料拷貝,但是如果外部的環境發生變化了,後續再呼叫makeWeaponRequest時,無法感知!@!原因是war這裡是wartime的一個copy,並不是直接引用!
當然,如果希望內部和外部完全同步,有一個可行的方法是,將wartime宣告為一個object或者array,在IIFE內部通過 object.property,array[index]方式來讀或者寫就可以實現內外完全同步了!看下面的簡單說明:
function replace(ref) { ref = {}; // this code does _not_ affect the object passed } function update(ref) { ref.key = 'newvalue'; // this code _does_ affect the _contents_ of the object } var a = { key: 'value' }; replace(a); // a still has its original value - it's unmodfied update(a); // the _contents_ of 'a' are changed
文字盒翻滾效果
var wordBox = $("#theWords"); var timer; timer = setTimeout(function(){ var argCallee = arguments.callee; var fSpan = $("#theWords span:first"); fSpan.animate({ marginTop:-20 },500,function(){ wordBox.append(fSpan); fSpan.css("margin-top","0"); timer = setTimeout(argCallee,3000); }); },3000); html: <div id="theWords" class="theScrollword"> <span style="margin-top: 0px;">不怕做不到只怕想不到。</span><span style="margin-top: 0px;">學而不思則罔!</span><span style="margin-top: 0px;">思而不學則殆 </span><span style="margin-top: 0px;">我聽我忘,我看我會,我做我懂 </span><span style="margin-top: 0px;">做個有價值的人。</span></div> css: .theScrollword { height: 20px; overflow: hidden; position: relative; margin: 20px 0 0; padding: 0 0 0 40px; float: left; display: inline; } .container .toparea .notice span { text-align: left; color: #fffeff; font-size: 14px; display: block; }
上面一段程式碼的原理是使用jquery的animate函式對第一個span的margin-top屬性來做動畫,並且不斷將第一個span移動到最後去
jquery document ready and window load
我們知道javascript在操作一個頁面的元素時,必須保證document is "ready"。 jQuery偵測readiness狀態。在$(document).ready()函式中的程式碼只有在頁面的Document Object Model(DOM)完全就緒後才會被執行(而對於未定義在ready handler中的javascript程式碼則基本上會在DOM完全構建完成之前執行!!!)。而在$(window).load(function(){...})中的程式碼則只有整個page的資源(images,css,iframes)都載入完成(或者timeout failure)後才被執行,而不是DOM一就緒就執行;
DOM就緒發生在HTML Document被瀏覽器接收(注意對應的JS也被載入執行了!!),並且解析成對應的DOM數後發生!。看看下面的示例程式碼:
<html> <head> <script src="https://code.jquery.com/jquery-1.9.1.min.js"></script> <script> $( document ).ready(function() { console.log( "document loaded" ); }); $( window ).load(function() { console.log( "window loaded" ); }); </script> </head> <body> <img src="http://xx.yy.com/build/images/internet.jpg" /> <iframe src="http://techcrunch.com"></iframe> </body> </html>
上面的程式碼將首先打出“document loaded”,隨後在img,iframe全部載入完成後,列印出"window loaded"
列出所有全域性空間的物件
有時我們希望看到在我們的頁面上有哪些可以操作的全域性物件,通過Object.keys(window)就可以輕鬆實現。更進一步,我們希望列印出物件,並且方便檢視,則可以使用下面的程式碼:
(function () { var keys=Object.keys( window ); for (var i in keys) { if (typeof window[keys[i]] != 'function') console.log(keys[i], window[keys[i]]); } })();
函式柯里化充分理解閉包,返回函式的概念
function add(value) { var helper = function(next) { console.log("value is: "+ value + "--line 481" ); value = typeof(value)==="undefined"?next:value+next; console.log("value is: " +value + "--line 483"); return helper; } helper.valueOf = function() { console.log("valueOf is called at 488"); return value; } return helper; } console.log(add(2)(3)(5)(7));
value is: 2--line 481
value is: 5--line 483
value is: 5--line 481
value is: 10--line 483
value is: 10--line 481
value is: 17--line 483
jstext.html:495 17
valueOf is called at 488
注意:valueOf是console.log(returnHelper)時js引擎自動會呼叫returnHelper.valueOf方法的~~~!
如何reset input file控制元件的選擇狀態以便能夠再次選擇同一檔案?
input file控制元件在首次選擇檔案後,如果我們取消remove掉了所選檔案,後面突然反悔又希望再次選中同一個檔案,由於該控制元件具有一個內在的邏輯是由於選過,不允許重複選擇,因此選擇無效,這時,一個簡單有效的方法是通過javascript設定該空間的type屬性
input.type = ''
input.type = 'file'
javascript中的陣列操作方法
在javascript中對陣列的操作總體上分為兩類:一種是mutation的也就是執行對應函式後原陣列將會被修改,一種是accessor,就是返回源陣列的部分資料,不會對原陣列做任何的修改。
mutation類的函式有:
array.reverse, array.splice, array.shift, array.unshift, array.sort
accessor類的函式有
array.concat, array.indexOf, array.join, array.lastIndexOf, array.slice
javascript regex正則
https://javascript.info/regexp-methods