點擊下方按鈕上傳圖片檢視預覽效果:
點我檢視程式碼範例
2016年6月30日 星期四
2016年6月29日 星期三
2016年6月26日 星期日
javascript 特性與觀念整理
紀錄目前為止個人覺得蠻重要的javascript特性和觀念:
以下程式碼,你能看出console的輸出結果嗎?
1、
var var1 = 'a';
function fun1 (var1) {
var1='b';
console.log(var1);
}
fun1(var1);
console.log(var1);
2、
var var2 = {
proper: 'a'
};
function fun2(var2) {
var2.proper = 'b';
console.log(var2.proper);
var var3 = var2;
console.log(var3.proper);
}
fun2(var2);
console.log(var2.proper);
console.log(var3.proper);
3、
var var4 = {
proper1: 'a'
};
function fun3(var4) {
var4 = {
proper1: 'b',
proper2: 'w'
};
console.log(var4.proper1);
console.log(var4.proper2);
}
fun3(var4);
console.log(var4.proper1);
console.log(var4.proper2);
4、
var var5 = {
proper1: 'a',
proper2: {}
};
function fun4(){
var var6 = var5,
proper1 = var6.proper1,
proper2 = var6.proper2;
proper1 = 'b';
console.log(var6.proper1);
proper2.attr = 'w';
proper2 = 'y';
console.log(typeof var6.proper2);
console.log(var6.proper2.attr);
var obj = {
properx: 'z'
};
var6.proper2.z = obj;
console.log(var6.proper2.z.properx);
return var6;
}
var var7 = fun4();
console.log(var5.proper1);
console.log(var5.proper2.attr);
var5 = '';
console.log(var7.proper2.attr);
console.log(var7.proper2.z);
console.log(var7.proper2.z.properx);
以下解答:
1、
var var1 = 'a';
function fun1 (var1) {
var1='b';
console.log(var1);
}
fun1(var1); //呼叫fun1並傳入global 變數var1的值(基本形態的字串'a')存入local變數var1之中,於fun1中修改了local變數var1的值為字串的'b',緊接著在console輸出local變數var1的值 'b'
console.log(var1);//輸出global變數var1的值'a'
//程式碼1執行結果驗證
2、
var var2 = {
proper: 'a'
};
function fun2(var2) {
var2.proper = 'b';
console.log(var2.proper);
var var3 = var2;
console.log(var3.proper);
}
fun2(var2);//呼叫fun2並傳入global變數var2的值(global物件形態指標),存入local變數var2,在函數內部對global物件的proper屬性值做修改,改為'b',接著console輸出這個屬性的值'b',接著宣告一個local變數var3,並將local var2的值(global 物件指標)賦於var3,接著console輸出global物件的proper屬性值'b'
console.log(var2.proper);//console輸出global var2的值(global物件)的proper屬性值'b'
console.log(var3.proper);//因scope限制,無法存取local變數var3的值(global物件的指標),於console輸出var3 is not defined,也就無法進一步讀取物件的proper屬性值
//程式碼2執行結果驗證
3、
var var4 = {
proper1: 'a'
};
function fun3(var4) {
var4 = {
proper1: 'b',
proper2: 'w'
};
console.log(var4.proper1);
console.log(var4.proper2);
}
fun3(var4);//呼叫fun3並傳入global變數var4的值(物件形態指標)存入local變數var4中,於函數內部對local變數var4做賦新值的動作,宣告一個local的物件存入其中,覆蓋掉原本的global物件指標,新物件擁有兩個屬性,接著console輸出local物件的兩個屬性值,分別為'b'和'w'
console.log(var4.proper1);//console輸出global物件的proper1屬性值'a'
console.log(var4.proper2);//global物件未定義proper2這個屬性,console輸出undefined
//程式碼3執行結果驗證
4、
var var5 = {
proper1: 'a',
proper2: {}
};
function fun4(){
var var6 = var5,
proper1 = var6.proper1,
proper2 = var6.proper2;
proper1 = 'b';
console.log(var6.proper1);
proper2.attr = 'w';
proper2 = 'y';
console.log(typeof var6.proper2);
console.log(var6.proper2.attr);
var obj = {
properx: 'z'
};
var6.proper2.z = obj;
console.log(var6.proper2.z.properx);
return var6;
}
var var7 = fun4();//呼叫func4,於函數內宣告local變數var6,並將global變數var5的值(global物件指標)賦於它,接著宣告兩個local變數proper1, proper2並分別將global物件的proper1屬性的值('a')與proper2屬性的值(global物件指標)賦予兩者,
接著修改local變數proper1的值為文字'b',接著console輸出global物件的proper1屬性值'a',接著為置於local變數proper2中的global物件新增一個名為attr的屬性,並賦予其值為文字'w',接著修改local變數proper2的值為文字'y',覆蓋掉原本的global物件指標,
接著console輸出置於local變數var6中的global物件的proper2屬性之形態,結果為object,然後接著console輸出其attr屬性值'w',接著宣告一個local變數obj,賦於其一個local物件,此物件擁有一個properx屬性,值為文字'z',接著為global物件的proper2屬性值(global物件指標),新增一個屬性名為z,並將local變數obj的值(local物件指標)賦予它,
然後console輸出置於global物件中的global屬性變數z中的local物件之properx屬性值'z',最後回傳local變數var6的值(與global變數var5相同的global物件指標)存於global變數var7中
console.log(var5.proper1);//console輸出置於global變數var5中的global物件的proper1屬性值'a'
console.log(var5.proper2.attr);//console輸出global物件的proper2屬性值(物件指標)的attr屬性值'w'
var5 = '';//修改global變數var5的值為''
console.log(var7.proper2.attr);//console輸出global變數var7的值(global物件指標,此時var5已解除與此物件的reference)的proper2屬性值(物件指標)的attr屬性值'w'
寫到這邊忽然領悟到{}物件形態是指標,無scope限制,文中'global物件'以及'local物件'之修詞並不恰當,應統一稱'物件形態指標'
console.log(var7.proper2.z);//因scope限制,無法存取z屬性中儲存的local物件,console輸出undefined => 更正,物件形態指標不受scope影響,console輸出Object {properx: "z"}
console.log(var7.proper2.z.properx);//因上列原因,無法進一步存取local物件的properx屬性,console輸出undefined => 更正,物件形態指標不受scope影響,console輸出屬性值'z'
//程式碼4執行結果驗證
記憶體管理:
未被任何變數參照的記憶體會被GC回收,然後釋放記憶體(滿足特定條件時,不一定即時)
var ref1 = {
proper1: 'abc'
};//ref1參照到此物件
var ref2 = ref1;//現在ref2也參照到該物件,該物件被兩個變數參照
ref1 = '';//ref1不再參照到該物件,剩ref2參照
ref2 = '';//現在物件{proper1: 'abc'}已無任何變數參照,將會被GC回收釋放記憶體
更詳細的解說可參考下列連結文章:
簡單理解 JavaScript 的記憶體管理機制
刪除變數使用delete關鍵字
以下程式碼,你能看出console的輸出結果嗎?
1、
var var1 = 'a';
function fun1 (var1) {
var1='b';
console.log(var1);
}
fun1(var1);
console.log(var1);
2、
var var2 = {
proper: 'a'
};
function fun2(var2) {
var2.proper = 'b';
console.log(var2.proper);
var var3 = var2;
console.log(var3.proper);
}
fun2(var2);
console.log(var2.proper);
console.log(var3.proper);
3、
var var4 = {
proper1: 'a'
};
function fun3(var4) {
var4 = {
proper1: 'b',
proper2: 'w'
};
console.log(var4.proper1);
console.log(var4.proper2);
}
fun3(var4);
console.log(var4.proper1);
console.log(var4.proper2);
4、
var var5 = {
proper1: 'a',
proper2: {}
};
function fun4(){
var var6 = var5,
proper1 = var6.proper1,
proper2 = var6.proper2;
proper1 = 'b';
console.log(var6.proper1);
proper2.attr = 'w';
proper2 = 'y';
console.log(typeof var6.proper2);
console.log(var6.proper2.attr);
var obj = {
properx: 'z'
};
var6.proper2.z = obj;
console.log(var6.proper2.z.properx);
return var6;
}
var var7 = fun4();
console.log(var5.proper1);
console.log(var5.proper2.attr);
var5 = '';
console.log(var7.proper2.attr);
console.log(var7.proper2.z);
console.log(var7.proper2.z.properx);
以下解答:
1、
var var1 = 'a';
function fun1 (var1) {
var1='b';
console.log(var1);
}
fun1(var1); //呼叫fun1並傳入global 變數var1的值(基本形態的字串'a')存入local變數var1之中,於fun1中修改了local變數var1的值為字串的'b',緊接著在console輸出local變數var1的值 'b'
console.log(var1);//輸出global變數var1的值'a'
//程式碼1執行結果驗證
2、
var var2 = {
proper: 'a'
};
function fun2(var2) {
var2.proper = 'b';
console.log(var2.proper);
var var3 = var2;
console.log(var3.proper);
}
fun2(var2);//呼叫fun2並傳入global變數var2的值(global物件形態指標),存入local變數var2,在函數內部對global物件的proper屬性值做修改,改為'b',接著console輸出這個屬性的值'b',接著宣告一個local變數var3,並將local var2的值(global 物件指標)賦於var3,接著console輸出global物件的proper屬性值'b'
console.log(var2.proper);//console輸出global var2的值(global物件)的proper屬性值'b'
console.log(var3.proper);//因scope限制,無法存取local變數var3的值(global物件的指標),於console輸出var3 is not defined,也就無法進一步讀取物件的proper屬性值
//程式碼2執行結果驗證
3、
var var4 = {
proper1: 'a'
};
function fun3(var4) {
var4 = {
proper1: 'b',
proper2: 'w'
};
console.log(var4.proper1);
console.log(var4.proper2);
}
fun3(var4);//呼叫fun3並傳入global變數var4的值(物件形態指標)存入local變數var4中,於函數內部對local變數var4做賦新值的動作,宣告一個local的物件存入其中,覆蓋掉原本的global物件指標,新物件擁有兩個屬性,接著console輸出local物件的兩個屬性值,分別為'b'和'w'
console.log(var4.proper1);//console輸出global物件的proper1屬性值'a'
console.log(var4.proper2);//global物件未定義proper2這個屬性,console輸出undefined
//程式碼3執行結果驗證
4、
var var5 = {
proper1: 'a',
proper2: {}
};
function fun4(){
var var6 = var5,
proper1 = var6.proper1,
proper2 = var6.proper2;
proper1 = 'b';
console.log(var6.proper1);
proper2.attr = 'w';
proper2 = 'y';
console.log(typeof var6.proper2);
console.log(var6.proper2.attr);
var obj = {
properx: 'z'
};
var6.proper2.z = obj;
console.log(var6.proper2.z.properx);
return var6;
}
var var7 = fun4();//呼叫func4,於函數內宣告local變數var6,並將global變數var5的值(global物件指標)賦於它,接著宣告兩個local變數proper1, proper2並分別將global物件的proper1屬性的值('a')與proper2屬性的值(global物件指標)賦予兩者,
接著修改local變數proper1的值為文字'b',接著console輸出global物件的proper1屬性值'a',接著為置於local變數proper2中的global物件新增一個名為attr的屬性,並賦予其值為文字'w',接著修改local變數proper2的值為文字'y',覆蓋掉原本的global物件指標,
接著console輸出置於local變數var6中的global物件的proper2屬性之形態,結果為object,然後接著console輸出其attr屬性值'w',接著宣告一個local變數obj,賦於其一個local物件,此物件擁有一個properx屬性,值為文字'z',接著為global物件的proper2屬性值(global物件指標),新增一個屬性名為z,並將local變數obj的值(local物件指標)賦予它,
然後console輸出置於global物件中的global屬性變數z中的local物件之properx屬性值'z',最後回傳local變數var6的值(與global變數var5相同的global物件指標)存於global變數var7中
console.log(var5.proper1);//console輸出置於global變數var5中的global物件的proper1屬性值'a'
console.log(var5.proper2.attr);//console輸出global物件的proper2屬性值(物件指標)的attr屬性值'w'
var5 = '';//修改global變數var5的值為''
console.log(var7.proper2.attr);//console輸出global變數var7的值(global物件指標,此時var5已解除與此物件的reference)的proper2屬性值(物件指標)的attr屬性值'w'
寫到這邊忽然領悟到{}物件形態是指標,無scope限制,文中'global物件'以及'local物件'之修詞並不恰當,應統一稱'物件形態指標'
console.log(var7.proper2.z);//因scope限制,無法存取z屬性中儲存的local物件,console輸出undefined => 更正,物件形態指標不受scope影響,console輸出Object {properx: "z"}
console.log(var7.proper2.z.properx);//因上列原因,無法進一步存取local物件的properx屬性,console輸出undefined => 更正,物件形態指標不受scope影響,console輸出屬性值'z'
//程式碼4執行結果驗證
記憶體管理:
未被任何變數參照的記憶體會被GC回收,然後釋放記憶體(滿足特定條件時,不一定即時)
var ref1 = {
proper1: 'abc'
};//ref1參照到此物件
var ref2 = ref1;//現在ref2也參照到該物件,該物件被兩個變數參照
ref1 = '';//ref1不再參照到該物件,剩ref2參照
ref2 = '';//現在物件{proper1: 'abc'}已無任何變數參照,將會被GC回收釋放記憶體
更詳細的解說可參考下列連結文章:
簡單理解 JavaScript 的記憶體管理機制
刪除變數使用delete關鍵字
2016年6月25日 星期六
javascript 語法效率實驗: 直接以陣列索引存取值以及先將值存入變數再存取
var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14];
var expTimes = 100000, test = 0;
//方式1
for (let i=0;i<expTimes;i++){
test = arr[9];
}
//方式2
var temp = arr[9];
for (let i=0;i<expTimes;i++){
test = temp;
}
何者速度會更快呢?
效率實驗
實驗結果先存入變數稍快,但差異不明顯
var expTimes = 100000, test = 0;
//方式1
for (let i=0;i<expTimes;i++){
test = arr[9];
}
//方式2
var temp = arr[9];
for (let i=0;i<expTimes;i++){
test = temp;
}
何者速度會更快呢?
效率實驗
實驗結果先存入變數稍快,但差異不明顯
javascript 語法效率實驗: 直接存取物件屬性以及先將物件屬性存入變數再存取
2016年6月22日 星期三
jquery 效率實驗:將$('target')結果先儲存到變數中的益處
jquery的運作模式,簡單講就是選擇目標然後執行指定動作,這裡要討論的是選擇目標這個動作對程式執行效率的影響
$('p').hide();
上面這列語法是隱藏所有的p元素,其底層運作是搜尋html文件中的所有p元素,再逐一修改其attr的style,設定其display為none
$('css selector') 這個語法包含了搜尋動作,所以先將搜尋結果儲存到變數裡,之後就不用重複搜尋,例如:
方式1:
$('p').hide();
$('p').show();
方式2:
var jqP = $('p');
jqP.hide();
jqP.show();
方式2相較於方式1,執行速度會更快
我們可以做個實驗驗證,程式碼在以下網址,進入後點擊左上"Run"按鈕即可在右下窗格看見執行結果,點擊按鈕即可進行實驗
(建議用電腦觀看,手機可能無法正常運行實驗)
(建議用電腦觀看,手機可能無法正常運行實驗)
從以上實驗結果可以看出速度的差異,速度差異和html文件中的元素數量成正比
(因為我們實驗的動作是對全部的p寫入class,所以若增加的元素是p,對整體速度影響更大,但其中有部份是寫入class造成,比較客觀的方式是加入其他元素,就主要會是搜尋的影響)
(因為我們實驗的動作是對全部的p寫入class,所以若增加的元素是p,對整體速度影響更大,但其中有部份是寫入class造成,比較客觀的方式是加入其他元素,就主要會是搜尋的影響)
另外假設同樣在一堆元素中尋找一個特定元素,使用id尋找和使用class尋找兩者比較起來,用id速度會比用class快
有興趣可以自行修改一下上述網址程式碼,賦予其中一個p以id屬性,再將jquery語法的p改成id,跑看看時間,再將id改成class,比較一下時間差異,會發現用id尋找比較快,不過不用是用id還是class,都是先將搜尋結果儲存到變數最快
雖然一般使用差異不大,但當專案規模變大時,程式碼的效率影響力也會成正比上升,這是一個概念,這個範例只是一個簡單的例子
以上分享。
2016年6月20日 星期一
cookie, session, localStorage, sessionStorage差異
cookie:
容量較小,儲存於client端,生命每次client向server提出request時都會傳輸至server,server回應時亦會回傳
session:
儲存於server端,於client端會建立cookie儲存sessionID,預設在瀏覽器標籤或是瀏覽器關閉時即會清除
localStorage:
容量較大(約5MB),儲存於client端,單純的本地端資料儲存空間
sessionStorage:
同localStorage,差別只在當瀏覽器標籤或是瀏覽器關閉時即清除
容量較小,儲存於client端,生命每次client向server提出request時都會傳輸至server,server回應時亦會回傳
session:
儲存於server端,於client端會建立cookie儲存sessionID,預設在瀏覽器標籤或是瀏覽器關閉時即會清除
localStorage:
容量較大(約5MB),儲存於client端,單純的本地端資料儲存空間
sessionStorage:
同localStorage,差別只在當瀏覽器標籤或是瀏覽器關閉時即清除
html javascript return false的應用
在下列情況下return false可防止html元素執行預設動作:
例1:
<a onclick="return confirm('are you sure?')" href="https//google.com.tw">go to google</a>
點擊"確定"(return true)才會前往google,否則(return false)無動作
例2:
<form action="">
<button onclick="return confirm('are you sure?')">click me</button>
</form>
點擊"確定"(return true)才會送出表單,否則(return false)無動作
需注意return false的接收者必須是元素本身,以下方式是無效的
onclick="myFunction()"
function myFunctoin() {
return confirm('are you sure?');
}
相關原因說明可參考下列這篇說明:
html onclick 屬性觸發的function如何取得元素物件
例1:
<a onclick="return confirm('are you sure?')" href="https//google.com.tw">go to google</a>
點擊"確定"(return true)才會前往google,否則(return false)無動作
例2:
<form action="">
<button onclick="return confirm('are you sure?')">click me</button>
</form>
點擊"確定"(return true)才會送出表單,否則(return false)無動作
需注意return false的接收者必須是元素本身,以下方式是無效的
onclick="myFunction()"
function myFunctoin() {
return confirm('are you sure?');
}
相關原因說明可參考下列這篇說明:
html onclick 屬性觸發的function如何取得元素物件
html onclick 屬性觸發的function如何取得元素物件
假設html文件中有一個a元素如下:
<a onclick="點擊連結時觸發的javascript程式碼" href="https://google.com.tw">click me</a>
onclick屬性是當使用者點擊元素時觸發其中的程式碼
很多時候我們會希望能取得a元素本身這個物件做進一步的判斷和處理,例如點擊時變更該元素的css屬性或是刪除該元素等等,那麼該如何達到目的呢?
首先我們要知道onclick="",其實 "" 背後代表的是一個匿名函數,是綁定到這個a元素的click事件的一個匿名函數, "" 就是隱形的function () 的 大括號,因此在這個函數內取得自身元素的最簡單方法就是"this"關鍵字:
onclick="console.log(this);" //其中的this就代表a這個元素
但是很多時候在點擊之後會需要做比較多的處理,不適合在inline屬性(直接寫在html元素裡面的屬性)上寫太多程式碼,此時就需要另外定義一個函數做處理
onclick="myFunction();"
<script>
function myFunction () {
console.log(this);
//注意! 此時這個this是global物件,也就是window物件,而非a元素
}
</script>
此時要如何取得元素物件呢?
方法1:
呼叫myFunction時將a元素物件做為參數傳遞
onclick="myFunction(this);" // 在隱形的匿名函數裡this是指a元素
function myFunction (tarObj) {
console.log(tarObj);
//此時tarObj代表在呼叫時傳入的this,也就是a元素
}
方法2:
以call或apply方法呼叫函數,並指定函數owner為a元素
先說明call的用法:
function test(a,b) {
console.log(a*b);
console.log(this);
}
這是一個擁有兩個參數的函數,使用call方法呼叫的語法如下:
test.call(<某個p元素>, 5, 3)
第一個參數會成為test函數內部的this所代表的元素
所以輸出結果會如下:
15
<p></p>
現在回到主題,
onclick="myFunction.call(this);"
// 在隱形的匿名函數裡this是指a元素,而call方法的第一個參數指定函數內部的this關鍵字代表的物件
function myFunction () {
console.log(this);
//此時的this就代表a元素,因為在使用call方法呼叫myFunction這個函數時,第一個參數傳入this(在當時環境下,代表a元素),而call的第一個參數,則是讓指定的元素成為被呼叫的函數中的this,有點抽象,因為都叫this,但代表的是不同的東西
}
以上分享
<a onclick="點擊連結時觸發的javascript程式碼" href="https://google.com.tw">click me</a>
onclick屬性是當使用者點擊元素時觸發其中的程式碼
很多時候我們會希望能取得a元素本身這個物件做進一步的判斷和處理,例如點擊時變更該元素的css屬性或是刪除該元素等等,那麼該如何達到目的呢?
首先我們要知道onclick="",其實 "" 背後代表的是一個匿名函數,是綁定到這個a元素的click事件的一個匿名函數, "" 就是隱形的function () 的 大括號,因此在這個函數內取得自身元素的最簡單方法就是"this"關鍵字:
onclick="console.log(this);" //其中的this就代表a這個元素
但是很多時候在點擊之後會需要做比較多的處理,不適合在inline屬性(直接寫在html元素裡面的屬性)上寫太多程式碼,此時就需要另外定義一個函數做處理
onclick="myFunction();"
<script>
function myFunction () {
console.log(this);
//注意! 此時這個this是global物件,也就是window物件,而非a元素
}
</script>
此時要如何取得元素物件呢?
方法1:
呼叫myFunction時將a元素物件做為參數傳遞
onclick="myFunction(this);" // 在隱形的匿名函數裡this是指a元素
function myFunction (tarObj) {
console.log(tarObj);
//此時tarObj代表在呼叫時傳入的this,也就是a元素
}
方法2:
以call或apply方法呼叫函數,並指定函數owner為a元素
先說明call的用法:
function test(a,b) {
console.log(a*b);
console.log(this);
}
這是一個擁有兩個參數的函數,使用call方法呼叫的語法如下:
test.call(<某個p元素>, 5, 3)
第一個參數會成為test函數內部的this所代表的元素
所以輸出結果會如下:
15
<p></p>
現在回到主題,
onclick="myFunction.call(this);"
// 在隱形的匿名函數裡this是指a元素,而call方法的第一個參數指定函數內部的this關鍵字代表的物件
function myFunction () {
console.log(this);
//此時的this就代表a元素,因為在使用call方法呼叫myFunction這個函數時,第一個參數傳入this(在當時環境下,代表a元素),而call的第一個參數,則是讓指定的元素成為被呼叫的函數中的this,有點抽象,因為都叫this,但代表的是不同的東西
}
以上分享
javascript closure
w3schools對於closure的註解與例子:
註解:
A closure is a function having access to the parent function scope, even after the parent function has closed.
例子:
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
add();
add();
add();
// the counter is now 3
closure可以產生不會重置的私有變數
註解:
A closure is a function having access to the parent function scope, even after the parent function has closed.
例子:
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
add();
add();
add();
// the counter is now 3
closure可以產生不會重置的私有變數
javascript call 和 apply的差別
在js裡,function也是物件,有兩個預設的方法用來觸發作用,call和apply,兩個方法的第一個參數都是指定function的owner,也就是this代表的物件
var myObject={}, myArray=[10,2];
function test (a,b) {
console.log(this);
return a*b;
}
test.call(myObject,10,2) //this為myObject return 20
test.apply(myObject,myArray) //this為myObject return 20
call和apply的差別僅在於參數的給定方式,call一對一傳入參數,apply則是傳入一個參數陣列
w3schools上對於strict模式和non-strict對這兩個方法的影響之說明:
In JavaScript strict mode, the first argument becomes the value of this in the invoked function, even if the argument is not an object.
In "non-strict" mode, if the value of the first argument is null or undefined, it is replaced with the global object.
function除了兩個內建的觸發方法之外,還有1個內建的屬性和1個方法,arguments.length屬性和toString()方法:
arguments.length屬性傳回接收到的參數數量
function myFunction(a, b) {
return arguments.length;
}
myFunction(5,6) //傳回2
toString()方法將function以文字形態傳回
function myFunction (a, b) {
return a * b;
}
var txt = myFunction.toString();
console.log(txt)
// console輸出如下內容
function myFunction (a, b) {
return a * b;
}
2016年6月19日 星期日
每日一步: t_sql 變數宣告後未賦值的狀態下初始值是null
t_sql 變數宣告後未賦值的狀態下初始值是null,若直接拿來做運算會導致結果為null
例如:
declare @name
slelect @name = @name + 姓名 + ' '
from 員工
select @name
查詢結果為:
null
因為@name初始值為null,null = null + 姓名 + ' ' 結果為null
應修正為:
declare @name = '' --賦予空值初始值
slelect @name = @name + 姓名 + ' '
from 員工
select @name
查詢結果就會是:
陳xx 李xx 唐xx
例如:
declare @name
slelect @name = @name + 姓名 + ' '
from 員工
select @name
查詢結果為:
null
因為@name初始值為null,null = null + 姓名 + ' ' 結果為null
應修正為:
declare @name = '' --賦予空值初始值
slelect @name = @name + 姓名 + ' '
from 員工
select @name
查詢結果就會是:
陳xx 李xx 唐xx
t_sql
區域變數宣告:區域變數範圍以GO關鍵字區隔
declare @var1 as varchar(30)
declare @var2 int, @var3 datetime
賦值:
方法1:
在宣告時直接賦值,例如 declare @var1 = 'mytext'
方法2:
set @var1 = 'book store'
set@var2 = 1
set@var3 = getdate()
方法3:
select @var1 = 'mytext'
查詢:
select @var1
select@var2
select @var3
查詢結果:
book store
1
2016-.......當時日期
例1:
declare @customer
select @customer = 客戶名稱
from 客戶
where 客戶名稱 = 4
select @customer
查詢結果:
會查詢客戶資料表中客戶名稱欄位值為4的資料,並將結果存到@customer中
最後再用select@customer 指令顯示出來
系統變數:
@@+變數名稱
例:
select @@VERSION -- 查詢SQL SERVER軟體版本
select @@LANGUAGE --查詢語言
select @@ROWCOUNT --回傳最後一次查詢結果列數
於訊息標籤輸出結果:
PRINT指令
例:
PRINT 'ABC'
PRINT 'ABC' + 'DEF'
PRINT 1
PRINT 1 + 1
訊息標籤內顯示之結果:
ABC
ABCDEF
1
2
IF判斷式:
例1:
declare @x = 1
if @x >2
PRINT '@x>2
else
PRINT '@x<2'
GO
輸出結果:
@x<2
例2:
if (select sum(單價) from 標標公司) > 1000
PRINT '標標公司產品總價大於1000
esle
PRINT '標標公司產品總價小於1000
GO
if 'Windows 使用手冊' in (select 書籍名稱 from 書籍)
PRINT '有Windows 使用手冊'
else
PRINT '無Windows 使用手冊'
GO
if 1000 > all (select 單價 from 標標公司)
PRINT '標標公司產品單價最高不超過1000
GO
while 迴圈:
例:
declare @id=0, @name='', @price=0, @count=1
while @id < 500
begin
@id+=1
select @name = 書籍名稱, @price = 單價
from 書籍
where bookId = @id
if @@ROWCOUNT = 0 break
if @price > 400 contiune
PRINT @name
if @count %3 =0 PRINT '------' -- 每3筆資料分隔
@count +=1
end
GO
以上程式碼查詢400元以上的書籍名稱,在訊息標籤輸出結果
switch條件式:以CASE關鍵字觸發
例1:
declare @a =3, @answer varchar(10)
set @answer = CASE @a
when 1 then 'a'
when 2 then 'b'
when 3 then 'c'
when 4 then 'd'
when 5 then 'e'
end
PRINT 'answer is ' + @answer
GO
輸出結果:
answer is c
例2:
select 公司名稱, 聯絡人 + case 性別
when '男' then '先生'
when '女' then '小姐'
else '敬啟者'
end as '聯絡人'
, 電話
from 客戶
查詢結果:
公司名稱 / 聯絡人 / 電話
xxx公司/xxx先生/xxxxx
xxx公司/xxx小姐/xxxxx
程式列跳躍指令GOTO:
例1:
declare @number =3
if (@number % 3 =0)
GOTO THREE
else
GOTO NOTTHREE
THREE:
PRINT '三的倍數'
GOTO THEEND
NOTTHREE:
PRINT '不是三的倍數'
THEEND:
GO
例2:
declare @num =0
start:
select @num +=1
if @num > 10 GOTO theend
if (@num % 2 =0) GOTO even
else GOTO odd
even:
PRINT cast(@num as char(2)) + 'is 偶數'
GOTO start
odd:
PRINT cast(@num as char(2)) + 'is 奇數'
GOTO start
theend:
declare @var1 as varchar(30)
declare @var2 int, @var3 datetime
賦值:
方法1:
在宣告時直接賦值,例如 declare @var1 = 'mytext'
方法2:
set @var1 = 'book store'
set@var2 = 1
set@var3 = getdate()
方法3:
select @var1 = 'mytext'
查詢:
select @var1
select
book store
1
2016-.......當時日期
例1:
declare @customer
select @customer = 客戶名稱
from 客戶
where 客戶名稱 = 4
select @customer
查詢結果:
會查詢客戶資料表中客戶名稱欄位值為4的資料,並將結果存到@customer中
最後再用select
系統變數:
@@+變數名稱
例:
select @@VERSION -- 查詢SQL SERVER軟體版本
select @@LANGUAGE --查詢語言
select @@ROWCOUNT --回傳最後一次查詢結果列數
於訊息標籤輸出結果:
PRINT指令
例:
PRINT 'ABC'
PRINT 'ABC' + 'DEF'
PRINT 1
PRINT 1 + 1
訊息標籤內顯示之結果:
ABC
ABCDEF
1
2
IF判斷式:
例1:
declare @x = 1
if @x >2
PRINT '@x>2
else
PRINT '@x<2'
GO
輸出結果:
@x<2
例2:
if (select sum(單價) from 標標公司) > 1000
PRINT '標標公司產品總價大於1000
esle
PRINT '標標公司產品總價小於1000
GO
if 'Windows 使用手冊' in (select 書籍名稱 from 書籍)
PRINT '有Windows 使用手冊'
else
PRINT '無Windows 使用手冊'
GO
if 1000 > all (select 單價 from 標標公司)
PRINT '標標公司產品單價最高不超過1000
GO
while 迴圈:
例:
declare @id=0, @name='', @price=0, @count=1
while @id < 500
begin
@id+=1
select @name = 書籍名稱, @price = 單價
from 書籍
where bookId = @id
if @@ROWCOUNT = 0 break
if @price > 400 contiune
PRINT @name
if @count %3 =0 PRINT '------' -- 每3筆資料分隔
@count +=1
end
GO
以上程式碼查詢400元以上的書籍名稱,在訊息標籤輸出結果
switch條件式:以CASE關鍵字觸發
例1:
declare @a =3, @answer varchar(10)
set @answer = CASE @a
when 1 then 'a'
when 2 then 'b'
when 3 then 'c'
when 4 then 'd'
when 5 then 'e'
end
PRINT 'answer is ' + @answer
GO
輸出結果:
answer is c
例2:
select 公司名稱, 聯絡人 + case 性別
when '男' then '先生'
when '女' then '小姐'
else '敬啟者'
end as '聯絡人'
, 電話
from 客戶
查詢結果:
公司名稱 / 聯絡人 / 電話
xxx公司/xxx先生/xxxxx
xxx公司/xxx小姐/xxxxx
程式列跳躍指令GOTO:
例1:
declare @number =3
if (@number % 3 =0)
GOTO THREE
else
GOTO NOTTHREE
THREE:
PRINT '三的倍數'
GOTO THEEND
NOTTHREE:
PRINT '不是三的倍數'
THEEND:
GO
例2:
declare @num =0
start:
select @num +=1
if @num > 10 GOTO theend
if (@num % 2 =0) GOTO even
else GOTO odd
even:
PRINT cast(@num as char(2)) + 'is 偶數'
GOTO start
odd:
PRINT cast(@num as char(2)) + 'is 奇數'
GOTO start
theend:
2016年6月18日 星期六
每日一步: html javascript canvas 的 strokeStyle 陷阱
canvas 的 strokeStyle屬性賦值可以用rgb和hex,但讀取值時回傳的是hex,而css的屬性設定賦值同樣可以用rgb和hex,但讀取值時回傳的是rgb,
直覺會認為賦值時用哪種格式,讀取時就會回傳該格式,但實際上不是,因此在讀取css顏色屬性和strokeStyle比對時不小心就會變成用rgb和hex比較,導致結果不如預期,要謹記。
直覺會認為賦值時用哪種格式,讀取時就會回傳該格式,但實際上不是,因此在讀取css顏色屬性和strokeStyle比對時不小心就會變成用rgb和hex比較,導致結果不如預期,要謹記。
2016年6月16日 星期四
每日一步: 限制html input元素內容只能輸入數字
在input元素上加入以下屬性:
onkeypress='return event.charCode >= 48 && event.charCode <= 57'
只有當輸入的內容為數字時才會顯示
但這無法限制中文輸入法產生的內容,中文輸入法需另外用js處理
onkeypress='return event.charCode >= 48 && event.charCode <= 57'
只有當輸入的內容為數字時才會顯示
但這無法限制中文輸入法產生的內容,中文輸入法需另外用js處理
每日一步: html dom node與elemet差異
html dom 語法有兩種回傳類別,一種是node,一種是element,差別在於element不含text和comment,node則全含,文字的空格也算是text node,不瞭解這點會造成意料之外的bug
例如element.children傳回指定元素的子元素,但不含text和comment
element.childNodes傳回指定元素的所有子元素node,包含text和comment
例如element.children傳回指定元素的子元素,但不含text和comment
element.childNodes傳回指定元素的所有子元素node,包含text和comment
2016年6月14日 星期二
2016年6月10日 星期五
每日一步: css box-sizing效果
box-sizing:border-box設定讓在設定padding時不會影響總寬高,而是內部調整,例如原本width:100px,設定padding-left:5px時,總寬會變105px,若是在box-sizing:border-box設定底下,總寬會是100px,含padding-left:5px
2016年6月9日 星期四
每日一步: css 讓border重疊,並且同時可正常顯示focus特效方法
讓border重疊可透過設定負值的margin,例如div1的右邊界要與div2的左邊界重疊,可設定div1的margin-right:-1px或是div2的margin-left:-1px即可
focus狀態邊框特效在邊界重疊的情況下通常會有一方會被遮住,解法為將被遮住的元素position設為relative,然後設定該元素的focus狀態變更其z-index,使其比另一個元素高即可,例如:
div1的右邊界和div2的左邊界重疊,focus div1時右邊界特效被div2遮住,此時設定div1的position為relative,然後設定div1:focus { z-index:n;},n要比div2的z-index高,即可正常顯示。
focus狀態邊框特效在邊界重疊的情況下通常會有一方會被遮住,解法為將被遮住的元素position設為relative,然後設定該元素的focus狀態變更其z-index,使其比另一個元素高即可,例如:
div1的右邊界和div2的左邊界重疊,focus div1時右邊界特效被div2遮住,此時設定div1的position為relative,然後設定div1:focus { z-index:n;},n要比div2的z-index高,即可正常顯示。
2016年6月5日 星期日
2016年6月2日 星期四
2016年6月1日 星期三
javascript let 和 var 的差別
1、scope的差別
在最外層宣告的時候,兩者都會是global scope,除此之外let範圍只在' { } ' block內部, 需要注意的是若是let使用為迴圈的遞增或遞減變數,每次執行迴圈的該變數都是獨立的scope,var 則是以function為層級
2、let不會hoist
var 的宣告會hoist,let不會
來看例子:
function test ( ) {
//alert(y)可正常運作
//alert(x)會出錯,x is not defined
for(var i=0 ; i<2 ; i++ ) {
//alert(y)可正常運作
//alert(x)會出錯,x is not defined
let x;
var y;
//alert(x)可正常運作
}
}
迴圈的情況
for (let i = 1; i <6; i++) {
setTimeout(function() {
console.log(i)
}, i * 1000)
}
每次的i都是獨立的
對照組
for (var i = 1; i <6; i++) {
setTimeout(function() {
console.log(i)
}, i * 1000)
}
是同一個i
迴圈的情況
for (let i = 1; i <6; i++) {
setTimeout(function() {
console.log(i)
}, i * 1000)
}
每次的i都是獨立的
對照組
for (var i = 1; i <6; i++) {
setTimeout(function() {
console.log(i)
}, i * 1000)
}
是同一個i
訂閱:
文章 (Atom)