nuxtjs + vuetifyjs
安裝 VeeValidate
nuxt.config.js
plugins\veeValidate.js
注意 : 預設無法在TypeScript中導入JSON文件,確保有以下設定
jsconfig.json
nuxtjs + vuetifyjs
安裝 VeeValidate
nuxt.config.js
plugins\veeValidate.js
注意 : 預設無法在TypeScript中導入JSON文件,確保有以下設定
jsconfig.json
自定物件 - 是可變的,由建立空白物件後,再加入功能
建立自定物件的方法(1)物件實字語法 (2)自訂建構式
物件實字語法 - var dog = { name:"名字", getname:function{ return name;} };
避免用物件建構式 new Object() 建立自己的物件,原因有...
1. 效能較差
2. Object 建構式可傳一個參數,會影響產生出物件的型別,如: new Object(3) => Number
自訂建構式 ( 命名慣例 - 手字母大寫 )
var Person = function ( name ) {
//var this = Object.create(Person.prototype); //背後的動作
this.name = name;
this.say = function () {
return "I am " + this.name ;
};
//return this; //背後的動作
//如果沒有 return 任一物件 , 背後會自動 return this , 如果 return 非物件 ( string , number , boolean ... ) 雖然不會發生錯誤 , 還是會 return this;
};
var vivian = new Person ("vivian"); //用自定建構式建立自定物件
vivian.say; // I am vivian
使用自定建構式一定要用 new MyObject() , 如果忘記 new , 在建構式中的 this 就會指向全域物件
也就是在瀏覽器中, this 就指向 window , 為了避免就種問題 , 可以改成
var Person = function ( name ) {
var that = {};
that.name = name;
that.say = function () {
return "I am " + that.name ;
};
return that;
//that 只是慣例 , 也可以用 self , me ...
};
還是有缺點, 這樣會失去與原型之間的連結
最好(建議)的方式
function Person ( arg ) {
if ( ! ( this instanceof arguments.callee ) ) { // 當函式被呼叫時 , 會產生 arguments
return new arguments.callee( arg );
}
//意思是 , 如果 this 的實體不是被呼叫者 ( 呼叫者忘了 new) , 就自動 new
//做點什麼事...
}
console.log( parseInt( "017" ) ); // 15
console.log( parseInt( "08" ) ); // 0
為什麼?? 因為 parseInt 的傳入值開頭是 "0" 就會當成 8 進位處理 ("0x" 是 16 進位)
"017" >>> 8 + 7 = 15
"08" >>> 因為超過 8 進位範圍 , 結果為 0
為了避免矛盾和意外的結果,最好指定基數參數。
console.log( parseInt( "017" , 10 ) ); // 17
或是改用以下方法將字串變數字 , 而且效能優於 parseInt()
+"08" // 結果是 8
Number("08") // 8
少用 eval(),使用 eval() 有安全疑慮,因為被執行的代碼(例如從網絡來)可能已被篡改。
同樣重要的是要記住,給 setInterval()、setTimeout() 和 Function() 構造函數傳遞字符串,大部分情況下,與使用 eval() 是類似的,因此要避免。在幕後,JavaScript 仍需要評估和執行你給程序傳遞的字符串:
// 反面示例
setTimeout("myFunc()", 1000);
setTimeout("myFunc(1, 2, 3)", 1000);
// 更好的
setTimeout(myFunc, 1000);
setTimeout(function () {
myFunc(1, 2, 3);
}, 1000);
若在 eval() 中宣告變數 , 會視為全域變數 , 建議改用 new Function()
eval( "var un = 1; console.log(un);"); // logs "1" <<< 不建議
new Function("var deux = 2; console.log(deux);")(); // logs "2"
(function () {
eval( "var trois = 3; console.log(trois);");
}()); // logs "3"
console.log(typeof un); // number
console.log(typeof deux); // "undefined"
console.log(typeof trois); // "undefined"
使用 eval() 可以直接使用外部的變數,而使用 Function() 不行
(function () {
var local = 1;
eval("local = 3; console.log(local)"); // logs "3"
console.log(local); // logs "3"
Function("console.log(typeof local);")(); // logs undefined
}());
JavaScript的變量在比較的時候會隱式類型轉換。這就是為什麼一些諸如:false == 0 或 「」 == 0 返回的結果是true。為避免引起混亂的隱含類型轉換,在你比較值和表達式類型的時候始終使用===和!==操作符。
var zero = 0;
if (zero === false) {
// 不執行,因為zero為0, 而不是false
}
// 反面示例
if (zero == false) {
// 執行了...
}
還有另外一種思想觀點認為==就足夠了===是多餘的。
例如,當你使用typeof你就知道它會返回一個字符串,所以沒有使用嚴格相等的理由。
然而,JSLint要求嚴格相等,它使代碼看上去更有一致性,可以降低代碼閱讀時的精力消耗。
(「==是故意的還是一個疏漏?」)
每個JavaScript環境有一個全局對象,當你在任意的函數外面使用 this 的時候可以訪問到。你創建的每一個變數都成了這個全局對象的屬性。在瀏覽器中,方便起見,該全局對象有個附加屬性叫做window,此window(通常)指向該全局對象本身。下面的代碼片段顯示了如何在瀏覽器環境中創建和訪問的全局變量:
var myglobal = "hello";//宣告變數,而 window.myglobal , window["myglobal"] , this.myglobal 都是指 myglobal
JavaScript通過函數管理作用域。在函數內宣告的變數只可在這個函數內使用,函數外面不可用,反之,全域變數就是在任何函數外面宣告的或是 在任何地方未宣告直接簡單使用的。當程序的兩個不同部分定義同名但不同作用的全局變量的時候,命名衝突在所難免,所以應該盡量少用全域變數。這裡要注意, 只有在函數內用 var 宣告才是區域變數,其餘的都會當做全域變數
var aa = 1; // 全域變數
bb = 2; // 全域變數 , 不推薦
function () {
var cc = 3; //區域變數
dd = 4; // 全域變數 , 不推薦
}
常犯的錯誤
function foo() {
var a = b = 0; // 等同於 var a = (b = 0);
// ...
}
這樣的寫法 , 無疑 a 是區域變數 , 但 b 沒有被宣告 , 所以 b 是全域變數 , 跟想像中不一樣吧!!
下面的寫法就好多了
function foo() {
var a, b;
a = b = 0; // 兩個都是區域變數
}
另一個疑問 - 全域變數有沒有宣告都一樣嗎?
隱式全域變數和明確定義的全域變數間有些小的差異,就是通過 delete 指令讓變量未定義的能力。
這表明,在技術上,隱式全域變數並不是真正的全域變數,但它們是全局對象的屬性。屬性是可以通過 delete 指令刪除的,而變數是不能刪除的。
// 定義三個全局變量
var global_var = 1;
global_novar = 2; // 全域變數 , 不推薦
(function () {
global_fromfunc = 3; // 全域變數 , 不推薦
}());
// 是否為全局對象的屬性
console.log("global_var : " + Object.prototype.hasOwnProperty.call(this, "global_var"));// true
console.log("global_novar : " + Object.prototype.hasOwnProperty.call(this, "global_novar"));// true
console.log("global_fromfunc : " + Object.prototype.hasOwnProperty.call(this, "global_fromfunc"));// true
// 試圖刪除
console.log("delete global_var : " + delete global_var); // false
console.log("delete global_novar : " + delete global_novar); // true
console.log("delete global_fromfunc : " + delete global_fromfunc); // true
// 測試該刪除
console.log("typeof global_var : " + typeof global_var); // "number"
console.log("typeof global_novar : " + typeof global_novar); // "undefined"
console.log("typeof global_fromfunc : " + typeof global_fromfunc); // "undefined"
一般會用 for-in 取得物件的屬性,但是物件有函數的話就會造成問題了
這時可以用hasOwnProperty()過濾原型屬性
// the object
var man = {
hands: 2,
legs: 2,
heads: 1
};
// somewhere else in the code
// a method was added to all objects
if (typeof Object.prototype.clone === "undefined") {
Object.prototype.clone = function () {};
}
for (var key in man) {
if (man.hasOwnProperty(key)) { // 過濾
console.log(key, ":", man[key]);
}
}
/* 控制台顯示結果
hands : 2
legs : 2
heads : 1
*/
不用hasOwnProperty()過濾的話
for (var key in man) {
console.log(key, ":", man[key]);
}
/*控制台顯示結果
hands : 2
legs : 2
heads : 1
clone: function()
*/
另外一種使用方法如下:
for (var key in man) {
if (Object.prototype.hasOwnProperty.call(man, key)) { // filter
console.log(key, ":", man[key]);
}
}
這樣寫的好處是可以防止man重新定義了hasOwnProperty方法導致的衝突。
如果不想寫這麼長的一串,你也可以這樣:
var key, hasOwn = Object.prototype.hasOwnProperty;
for (key in man) {
if (hasOwn.call(man, key)) { // filter
console.log(key, ":", man[key]);
}
}
變數/函式宣告將被提至該生命區塊的開端(hoisting)
var str = "global"; //全域變數
function f () { //全域函式
return "global function";
}
function hoistMe(){
alert(str); //undefined
alert(f()); //local function
var str = "local"; //宣告 hoist
function f(){ //宣告&實做 都 hoist
return "local function";
}
}
hoistMe();
你可能會以為第一個alert彈出的是"global",第二個彈出"global function"
事實上...第一個alert會彈出"undefined",第二個彈出"local function"
是因為變數/函式宣告將被提至該生命區塊的開端,實際運作如下:
function hoistMe(){
var str;//宣告 hoist
function f(){ //宣告&實做 都 hoist
return "local function";
}
alert(str); //undefined
alert(f()); //local function
str = "local";
// f() hoist 到上面去了/...
}
因此,為了避免這種混亂,最好是預先宣告你想使用的全部變數/函式。
原來現在大部分的瀏覽器都支援console.log(),還有其他幫助開發者除錯的功能,以後javascript除錯比較方便了^^
怎麼把瀏覽器的除錯工具叫出來咧??
IE9:工具列->[工具]->[F12開發者工具]或直接按F12
FireFox:工具列->[網頁開發者]
Chrome:工具列->[工具]->[開發者工具]或網頁右鍵->[檢查元素]
在javascript中可以直接使用console.log()
console.log("ABC");
看了 套件 mchain.js 的原始碼
其中開頭結尾看不懂以及為什麼在 script 中可以直接使用 mchain
所以了解一下這是什麼樣的寫法...
( function(_global){
//程式碼
_global.mchain = new _global.mchainClass();
} ) ( this );
這裡的 this 其實會是 window 物件
上面的程式碼就是在 window 物件加一個 mchain 屬性
然後 在 script 中可以直接使用 mchain (等於是 window.mchain)
簡單說...
JavaScript 可以直接用一組小括號 "()" 包覆一個匿名函式,然後後面再接一組小括號 "()" 表示呼叫這個匿名函式
而第二組小括號中就可以放置這個匿名函式的參數
(
匿名函式
) (匿名函式的參數) //網頁 load 時 就執行
var a1 = "123" , a2 = "456";
(function(b1,b2){
alert("我在裡面:"+b1+b2)
})(a1,a2);
alert("我在外面:"+a1+a2)
另外~
因為這種寫法很特殊,用的是小括號 "()" 開始的
如果上一行程式碼沒有分號 ";" 結尾就會出問題,難保引用一些縮減後套件,沒有最後的分號 ";"
所以養成小習慣,前面多加一個分號 ";" ,會安全一點
;(
匿名函式
) (匿名函式的參數) //網頁 load 時 就執行