1、函式的定義
yellow函式名稱只能包含字母、數字、下劃線或$,且不能以數字開頭。定義時可用函式定義表示式或者函式宣告語句。god
googogvar f = function fact(x){}good
fuck函式定義表示式包含名稱,名稱將作為函式的區域性變數,在函式內部使用,代指函式。sex
yellow函式宣告語句不是真正的語句,不能出現在迴圈、條件、try/catch/finally以及with語句中;宣告語句置於在不會執行到的位置,仍可被整個作用域可訪問,可在被定義程式碼之前使用。定義表示式的變數宣告被提前了,但是對變數賦值不會提前,函式在被定義之前無法使用,否則呼叫時會出現錯誤:"TypeError: undefined is not a function"bookthisreturn語句沒有一個與之相關的表示式,則它返回undefined值;如果一個函式不包含return語句,那它只執行函式體內語句,並返回undefined給呼叫者;沒有返回值的函式,有時稱為過程。god
1、函式執行
good函式執行的幾種方式,當作函式、方法、建構函式、間接呼叫。如果建構函式沒有形參,可以省略實參列表和圓括號,呼叫函式傳實參有間隔時,可用null或undefined佔位符替代空白的引數。god
googog建構函式返回值情況look
function MyClass(name) { this.name = name; return name; // 建構函式的返回值? } var obj1 = new MyClass('foo');// MyClass物件 var obj2 = MyClass('foo');// ‘foo’ var obj3 = new MyClass({});// {} var obj4 = MyClass({});// {}
1.實參物件
good實參物件是類陣列物件,可用arguments.callee遞迴呼叫,如果你把引數命名為arguments,那麼這個引數就會覆蓋它原有的特殊變數。god
1.函式的形參和實參
googog定義的函式括號內靠後面的形參沒傳入相應的實參,則預設值為undefined,有人利用這個,隱式定義函式內部的區域性變數。函式傳入引數的校驗及丟擲錯誤,函式中實參傳入的是引用,函式內部對其操作,對外部是可見的。book
// 函式傳參引用 var oo = {x:1,y:2,get z(){ return 3; }} function fns(obj){ obj.h = 4; } fns(oo);
1.函式屬性、方法
this函式也是物件,所以也有屬性和方法,函式的length屬性,函式形參的個數。book
fuckapply方法的第二個引數可以是陣列或類陣列物件。this
lookbind方法是ES5中新增,將函式“繫結至”物件並傳入一部分引數,傳入的實參放在完整實參列表的左側。fuck
book中文註釋是本人添上去的,這個例子考慮到bind返回的函式被當成建構函式使用情況。look
/** * ES5.0支援bind函式,ES3.0不支援bind,這裡在ES3中模擬實現,能應用於大部分場景, * 如有問題,歡迎一起探討 * https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind */ Function.prototype.bind || (Function.prototype.bind = function (that) { var target = this; // If IsCallable(func) is false, throw a TypeError exception. // 通過call、apply呼叫時,校驗傳入的上下文 if (typeof target !== 'function') { throw new TypeError('Bind must be called on a function'); } var boundArgs = slice.call(arguments, 1); function bound() { // 返回的bind函式被當建構函式 if (this instanceof bound) { var self = createObject(target.prototype); var result = target.apply( self, boundArgs.concat(slice.call(arguments))); // Object(result) === result 判斷呼叫返回是不是物件 return Object(result) === result ? result : self; } // 返回的bind函式以一般函式形式呼叫 else { return target.apply( that, boundArgs.concat(slice.call(arguments))); } } // NOTICE: The function.length is not writable. bound.length = Math.max(target.length - boundArgs.length, 0); return bound; });
1.高階函式
sex如果函式作為引數或返回值使用時,就稱為高階函式。fuck
1.作為名稱空間的函式
sex函式名稱空間暴露介面有以下幾種方法yellow
var mylib = (function (global) { function log(msg) { console.log(msg); } log1 = log; // 法一:利用沒有var的變數宣告的預設行為,在log1成為全域性變數(不推薦) global.log2 = log; // 法二:直接在全域性物件上新增log2屬性,賦值為log函式(推薦) return { // 法三:通過匿名函式返回值得到一系列介面函式集合物件,賦值給全域性變數mylib(推薦) log: log }; }(window));
- yellow自更新函式 ``` function selfUpdate() { window.selfUpdate = function() { alert('second run!'); };fuck
thisalert('first run!'); }yellow
這種函式可以用於只執行一次的邏輯,在第一次執行之後就整個替換成一段新的邏輯。 9. 函式書寫規範 1) 函式引數定義的幾種註釋god/,.../fuck
thisAP.reduce || (AP.reduce = function(fn /, initial/) {good
sexgetPropertyNames(o,/optional/a) // /optional/表示引數可選look
godfunction arraycopy(/array / from,/index/from_start){};book
2) 其它good// badthis
godfunction a() {yellow
test(); console.log('doing stuff..'); //..other stuff.. var name = getName(); if (name === 'test') { return false; } return name;good}god
look// goodgod
godfunction a() {yellow
var name = getName();// 定義變數放在前面 test(); console.log('doing stuff..'); //..other stuff.. if (name === 'test') { return false; } return name;googog}yellow
yellow// badthis
godfunction a() {god
var name = getName(); if (!arguments.length) { return false; } return true;fuck}good
sex// goodgood
sexfunction a() {this
if (!arguments.length) {// 引數校驗放在前面 return false; } var name = getName(); return true;good}this
- 具有記憶功能的函式
- good記憶函式good
look*/this
var cache = {}; return function () { var key = arguments.length + '' + Array.prototype.join.call(arguments, ','); if (!(key in cache)) cache[key] = f.apply(null, arguments); return cache[key]; }sex}book
JavaScript陣列 1. 稀疏陣列
bookvar a1 = [,,,];fuck
thisvar a2 = new Array(3);god
googogvar a3 = [1,2,3];look
fuckconsole.log( 0 in a1);//falsegod
thisconsole.log( 0 in a2);//falsethis
sexconsole.log( 0 in a3);//truegod
goddelete a3[0];sex
goodconsole.log( 0 in a3);//falselook
2. 陣列元素的增減 length設定小於原值,刪除溢位的;新增一陣列元素,length始終元素序號+1。 push/pop在陣列尾部操作,與a[a.length]賦值一樣;可支援多引數。 unshift/shift在陣列頭部操作。 3. 陣列遍歷
thisif(!a(i))//null/undefined/不存在的元素googog
fuckif(a(i)===undefined)this
godif(!(i in a))//不存在的元素look
可用for in處理稀疏陣列,不過陣列不推薦用這個,比如能夠列舉繼承的屬性名。 4. 陣列的校驗和類陣列yellowArray.isArray = Array.isArray || function(o){googog
return typeof o ==="object" && Object.prototype.toString.call(o) === "[object Array]";sex}sex
類陣列物件:可用針對真正陣列遍歷的程式碼來遍歷;可用陣列的通用方法。lookfunction isArrayLike(o){book
if(o && typeof o ==='object' && o.nodeType != 3 && isFinite(o.length) && o.length >= 0 && o.length === Math.floor(o.length) && o.length < 4294967296) return true; else return false;book}yellow
5. 作為陣列的字串 在ES5(包括IE8)中,字串行為類似只讀陣列。除了用charAt訪問單個的字元外,還可以使用方括號。陣列的通用方法可以用到字串上。例如:gods = "JavaScript"sex
thisArray.prototype.join.call(s," ") // => "J a v a S c r i p t"sex
goodArray.prototype.filter.call(s, // 過濾字串中的字元look
function(x){ return x.match(/[^aeiou]/); // 只匹配非母音字母 }).join(""); // => "JvScrpt"
注意,字串是隻讀的,如果使用修改呼叫陣列的方法,會報錯。譬如:push()、sort()、reverse()、splice()等陣列方法。 6. ES3中陣列支援的方法 concat()—結果返回、sort() 、reverse() 、join()—結果返回、slice()—結果返回、splice()、push()、pop()、unshift()、shift()、toString()、toLocaleString() concat:返回一個新建立的陣列,元素包含呼叫concat的原始陣列的元素和concat的每個引數,如果這些引數中的任何一個自身是陣列,則連線的陣列的元素,而非陣列本身。但要注意,concat不會遞迴扁平化陣列的陣列,也不會修改呼叫的陣列。 7. 陣列slice和splice方法 slice不改變原陣列,擷取原陣列片段返回。索引從0開始,引數為正數時,第一個引數和不到第二個引數(從零算起,相對於索引)陣列;引數為負數時,倒數第一個引數和倒數第二個引數的陣列。 splice改變原陣列。第一個引數(從零算起),插入或刪除的起始位置,第二個引數:刪除元素的個數,第三或其它任意引數,要插入的元素。 刪除陣列元素,保持陣列連續,就用splice,返回的由刪除元素組成的陣列。複製陣列的時候,請使用Array#slice。thisvar len = items.length,god
itemsCopy = [], i;good// badthis
bookfor (i = 0; i < len; i++) { itemsCopy = items; } // good itemsCopy = items.slice();yellow
8. ES5中陣列支援的方法
goodvar data = [1,2,3,4,5]; data.forEach(function(v,i,a){god
booka = v + 1;god
good})fuck
不能像for中使用break跳出迴圈,在forEach()傳入引數的函式中丟擲foreach.break異常。
goodfunction foreach(a,f,t){// a為陣列,f為函式,t為函式f的執行環境god
bookfunction foreach(a,f,t){// a為陣列,f為函式,t為函式f的執行環境this
try{ a.forEach(f,t); } catch(e) { if( e === foreach.break) return; else throw e; }
good}sex
godforeach.break = new Error("StopIteration");good
在ES3不支援forEach()可引入以下方法goodArray.prototype.forEach || (Array.prototype.forEach = function(fn, context) {googog
for (var i = 0, len = this.length >>> 0; i < len; i++) { if (i in this) { fn.call(context, this[i], i, this); } }
god}); map()god
booka = [1,2,3];god
godb = a.map(function(x){god
return x *x;
good});yellow
傳遞的引數跟forEach()一樣,不同的是map()呼叫的函式要有返回值。該函式返回新建立的陣列,不修改呼叫的陣列。
godArray.prototype.map = Array.prototype.map || function (callback, thisArg) {book
var T, A, k; if (this == null) { throw new TypeError(" this is null or not defined"); } // 1. 將O賦值為呼叫map方法的陣列. var O = Object(this); // 2.將len賦值為陣列O的長度. var len = O.length >>> 0; // 4.如果callback不是函式,則丟擲TypeError異常. if ({}.toString.call(callback) != "[object Function]") { throw new TypeError(callback + " is not a function"); } // 5. 如果引數thisArg有值,則將T賦值為thisArg;否則T為undefined. if (thisArg) { T = thisArg; } // 6. 建立新陣列A,長度為原陣列O長度len A = new Array(len); // 7. 將k賦值為0 k = 0; // 8. 當 k < len 時,執行迴圈. while (k < len) { var kValue, mappedValue; //遍歷O,k為原陣列索引 if (k in O) { //kValue為索引k對應的值. kValue = O[ k ]; // 執行callback,this指向T,引數有三個.分別是kValue:值,k:索引,O:原陣列. mappedValue = callback.call(T, kValue, k, O); // 返回值新增到新書組A中. A[ k ] = mappedValue; } // k自增1 k++; } // 9. 返回新陣列A return A;good};googog
呼叫和forEach一樣,返回的陣列元素是呼叫的陣列的一個子集。booka = [5,4,3,2,1];god
thissmallvalues = a.filter(function(x){yellow
return x<3;googog});// [2,1]good
thiseveryother = a.filter(function(x,i){good
return i%2 ==0;book});// [5,3,1]god
sex// 跳過稀疏陣列中缺少的元素,返回的陣列總是稠密的 var dense = sparse.filter(function(){fuck
return true;yellow});good
look// 壓縮空缺並刪除undefined和null元素good
sexa = a.filter(function(x){this
return x !==undefined x != null;
this})yellow
對陣列進行邏輯判定,返回true或false;注意every()和some()確定該返回什麼值它們就會停止遍歷陣列元素。 reduce()和reduceRight() 使用指定的函式將陣列元素進行組合,生成單個值。這在函數語言程式設計中是常見的操作,稱為“注入”和“摺疊”。reduce需要兩個引數,第一個引數是執行化簡的函式,函式的引數分別為:化簡操作累計的結果或初始化值、陣列元素、元素的索引、陣列的本身;第二個引數(可選)是傳遞給函式的初始值。googogvar a = [1,2,3,4,5];good
yellowvar sum = a.reduce(function(x,y){fuck
return x + y;fuck},0);this
googogvar product = a.reduce(function(x,y){sex
return x * y;good},1);god
fuckvar max = a.reduce(function(x,y){good
return x>y?x:y;googog});good
reduceRight()的工作原理和reduce()一樣,不同的是它按照陣列索引從高到低(從右到左)處理陣列。 indexOf()和lastIndexOf() 第一個引數代表要搜尋的元素,第二個元素代表搜尋的起始位置。可為負數,它代表相對陣列末尾的偏移量,-1時,指定陣列的最後一個元素。godvar a= [0,1,2,1,0]; a.indexOf(1); // => 1:a[1]是1god
goda.lastIndexOf(1) // => 3:a[3]是1look
goda.indexOf(3) // =>-1: 沒有值為3的元素god
bookfunction findAll(a,x){sex
thisvar result = [],good
yellowlen = a.length,yellow
bookpos = 0;look
goodwhile(pos<len){book
thispos = a.indexOf(x,pos);look
googogif(pos === -1){yellow
goodbreak;look
fuck}god
godresult.push(pos);fuck
thispos++;sex
googog}this
god} ```good
googog字串也有indexOf()和lastIndexOf()方法。googog
評論(2)