hoisting
http://openwares.net/js/javascript_declaration_hoisting.html
map梭依、reduce
練習(xí):不要使用JavaScript內(nèi)置的parseInt()函數(shù)办斑,利用map和reduce操作實現(xiàn)一個string2int()函數(shù):
return [].slice.call(s).map(function(x){return x/1}).reduce(function(x, y){return x*10 + y})
JS隱式轉(zhuǎn)換
Javascript 在遇到算數(shù)運算符(-
轩勘、*
赘艳、/
和%
)的時候會在運算之前將參與運算的雙方轉(zhuǎn)換成數(shù)字堕仔。
注意+
加號特殊哦~
練習(xí):希望利用map()把字符串變成整數(shù)
var arr = ['1', '2', '3'];
var r;
r = arr.map(parseInt);
但是結(jié)果卻是[1, NaN, NaN]
參考Array.prototype.map
原因是:
arr.map(callback[, thisArg])
Parameters
- callback
Function that produces an element of the new Array, taking three arguments:
-- currentValue
The current element being processed in the array.也就是array中需要處理的元素
-- index
The index of the current element being processed in the array.上面那個元素在array中的index
-- array
The array map was called upon.
- thisArg
Optional. Value to use as this when executing callback. Default value is the Window object
callback函數(shù)傳遞三個參數(shù)currentValue卓研, index盏檐,array,而ParseInt需要兩個參數(shù)芯咧,PareseInt會把map傳過來的第二個參數(shù)index 0牙捉,1竹揍,2作為數(shù)制參數(shù)十進制,一進制邪铲,二進制芬位,因此1被轉(zhuǎn)為1 ,2和3 因為不符合一進制带到,二進制所以返回NaN
filter
filter也是一個常用的操作昧碉,它用于把Array的某些元素過濾掉,然后返回剩下的元素揽惹。
和map()類似被饿,Array的filter()也接收一個函數(shù)。和map()不同的是永丝,filter()把傳入的函數(shù)依次作用于每個元素锹漱,然后根據(jù)返回值是true還是false決定保留還是丟棄該元素箭养。
例如慕嚷,把一個Array中的空字符串刪掉,可以這么寫:
var arr = ['A', '', 'B', null, undefined, 'C', ' '];
var r = arr.filter(function (s) {
return s && s.trim(); // 注意:IE9以下的版本沒有trim()方法
});
r; // ['A', 'B', 'C']
arguments
JavaScript還有一個免費贈送的關(guān)鍵字arguments
毕泌,它只在函數(shù)內(nèi)部起作用喝检,并且永遠指向當(dāng)前函數(shù)的調(diào)用者傳入的所有參數(shù)。即使函數(shù)不定義任何參數(shù)撼泛,還是可以拿到參數(shù)的值:
function abs() {
if (arguments.length === 0) {
return 0;
}
var x = arguments[0];
return x >= 0 ? x : -x;
}
abs(); // 0
abs(10); // 10
abs(-9); // 9
實際上arguments
最常用于判斷傳入?yún)?shù)的個數(shù)挠说。你可能會看到這樣的寫法:
// foo(a[, b], c)
// 接收2~3個參數(shù),b是可選參數(shù)愿题,如果只傳2個參數(shù)损俭,b默認為null:
function foo(a, b, c) {
if (arguments.length === 2) {
// 實際拿到的參數(shù)是a和b,c為undefined
c = b; // 把b賦給c
b = null; // b變?yōu)槟J值
}
// ...
}
要把中間的參數(shù)b變?yōu)椤翱蛇x”參數(shù)潘酗,就只能通過arguments判斷杆兵,然后重新調(diào)整參數(shù)并賦值。
例子:
實現(xiàn)函數(shù)useArguments
仔夺,返回所有調(diào)用參數(shù)相加后的結(jié)果琐脏。
你可能會醬紫寫。但這是錯的缸兔!
function useArguments() {
return arguments.reduce(function(x, y){
return x+y;
})
}
注意:arguments類似Array但它不是一個Array日裙,所以它的原型上沒有reduce方法,我們要做的就是讓arguments來調(diào)用Array.prototype上的方法(用到call或者apply)惰蜜,或者干脆把arguments變?yōu)閿?shù)組昂拂。
如何把一個偽數(shù)組轉(zhuǎn)變成真正的數(shù)組呢?
Array.prototype.slice.call(arguments)
我們可以這樣寫
function useArguments() {
return Array.prototype.slice.call(arguments).reduce(function(x,y){
return x+y;
})
}
//或者
function useArguments() {
return [].slice.call(arguments).reduce(function(x,y){
return x+y;
})
}
或者讓arguments來調(diào)用Array.prototype上的方法抛猖。
function useArguments() {
return [].reduce.call(arguments, function(x,y){
return x+y;
})
}
因為slice
,reduce
都是Array.prototype上的方法格侯,用call或者apply來改變當(dāng)前對象為arguments再調(diào)用即可路克。
PS: concat函數(shù)用于連接兩個數(shù)組,返回新的連接好的數(shù)組养交,而不會改變原數(shù)組精算。
函數(shù)的長度
函數(shù)的長度也就是函數(shù)的length屬性,指的是函數(shù)的形參的個數(shù)碎连,不是傳入的參數(shù)個數(shù)哦灰羽。
function test1(){
console.log(test1.length);
}
test1(a,b,c); // 0
柯里化(currying)
柯里化是把接受多個參數(shù)的函數(shù)變換成接受一個單一參數(shù)(最初函數(shù)的第一個參數(shù))的函數(shù),并且接受余下的參數(shù)且返回結(jié)果鱼辙。
題目描述
已知 fn 為一個預(yù)定義函數(shù)廉嚼,實現(xiàn)函數(shù) curryIt,調(diào)用之后滿足如下條件:
1倒戏、返回一個函數(shù) a怠噪,a 的 length 屬性值為 1(即顯式聲明 a 接收一個參數(shù))
2、調(diào)用 a 之后杜跷,返回一個函數(shù) b, b 的 length 屬性值為 1
3傍念、調(diào)用 b 之后,返回一個函數(shù) c, c 的 length 屬性值為 1
4葛闷、調(diào)用 c 之后憋槐,返回的結(jié)果與調(diào)用 fn 的返回值一致
5、fn 的參數(shù)依次為函數(shù) a, b, c 的調(diào)用參數(shù)
var fn = function (a, b, c) {return a + b + c};
curryIt(fn)(1)(2)(3); //6
caller和callee
答案:(目前不太懂淑趾,貌似不讓用callee屬性)
function curryIt(fn) {
//獲取fn參數(shù)的數(shù)量
var n = fn.length;
//聲明一個數(shù)組args
var args = [];
//返回一個匿名函數(shù)
return function(arg){
//將curryIt后面括號中的參數(shù)放入數(shù)組
args.push(arg);
//如果args中的參數(shù)個數(shù)小于fn函數(shù)的參數(shù)個數(shù)阳仔,
//則執(zhí)行arguments.callee(其作用是引用當(dāng)前正在執(zhí)行的函數(shù),這里是返回的當(dāng)前匿名函數(shù))扣泊。
//否則近范,返回fn的調(diào)用結(jié)果
if(args.length < n){
return arguments.callee;
}else return fn.apply("",args);
}
}
Number.toString()方法
Number類型的toString()方法比較特殊,有默認模式和基模式兩種延蟹。
//默認模式的例子:
var num1 = 10;
var num2 = 10.0;
alert(num1.toString());//輸出"10"
alert(num2.toString());//輸出"10"
//無論你用什么表示法聲明數(shù)字评矩,默認模式只是按十進制返回。
//基模式的例子:
var num1 = 10;
alert(num1.toString(2));//輸出1010
alert(num1.toString(8));//輸出12
alert(num1.toString(16));//輸出A
全局對象的parseInt()方法和parseFloat()方法
parseInt() 函數(shù)可解析一個字符串等孵,并返回一個整數(shù)稚照。
1、解析字符串俯萌,直到不能解析為止
2果录、進制轉(zhuǎn)化中,解析字符串咐熙,直到不能解析為止
document.write(parseInt("123") + "<br/>"); //123
document.write(parseInt("1abc23") + "<br/>"); //1
document.write(parseInt("123abc") + "<br/>"); //123
document.write(parseInt("abc") + "<br/>"); //NaN
document.write(parseInt("100",2) + "<br/>"); //4弱恒,以二進制形式解析
document.write(parseInt("123",2)); //1,因為2棋恼、3不能解析
二進制轉(zhuǎn)換
題目:將給定數(shù)字轉(zhuǎn)換成二進制字符串返弹。如果字符串長度不足 8 位锈玉,則在前面補 0 到滿8位。
function convertToBinary(num) {
var tmp = num.toString(2).split('');
while(tmp.length < 8){
[].unshift.call(tmp, 0)
//tmp.unshift(0);
}
return tmp.join('');
}
Array.unshfit()
unshift()
方法可向數(shù)組的開頭添加一個或更多元素义起,并返回新的長度請注意拉背,unshift() 方法不創(chuàng)建新的創(chuàng)建,而是直接修改原有的數(shù)組默终。
String.split()
split()
方法用于把一個字符串分割成字符串?dāng)?shù)組椅棺。這樣才能通過call使用數(shù)組原型鏈上的方法啊。
Array.join()
Array.join
執(zhí)行的操作與String.split()
執(zhí)行的操作是相反的齐蔽。join() 方法用于把數(shù)組中的所有元素放入一個字符串
Array.slice()
slice(0两疚,-1)如果是負數(shù),那么它規(guī)定從數(shù)組尾部開始算起的位置含滴。也就是說诱渤,-1 指最后一個元素,-2 指倒數(shù)第二個元素谈况,以此類推勺美。http://www.w3school.com.cn/jsref/jsref_slice_array.asp
Array.splice()
splice() 方法向/從數(shù)組中添加/刪除項目,然后返回被刪除的項目鸦做。該方法會改變原始數(shù)組励烦。
http://www.w3school.com.cn/jsref/jsref_splice.asp
arrayObject.splice(index,howmany,item1,.....,itemX)
splice() 方法可刪除從 index 處開始的零個或多個元素谓着,并且用參數(shù)列表中聲明的一個或多個值來替換那些被刪除的元素泼诱。
如果從 arrayObject 中刪除了元素,則返回的是含有被刪除的元素的數(shù)組赊锚。
Number.toFixed()
精確小數(shù)到多少位http://www.w3school.com.cn/jsref/jsref_tofixed.asp
遍歷屬性
function iterate(obj) {
var result = [];
for (var key in obj){
if(obj.hasOwnProperty(key)){
result.push(key+": "+obj[key])
}
}
return result;
}
幾條規(guī)則
- 不要使用
new Number()
治筒、new Boolean()
、new String()
創(chuàng)建包裝對象舷蒲; - 用
parseInt()
或parseFloat()
來轉(zhuǎn)換任意類型到number耸袜; - 用
String()
來轉(zhuǎn)換任意類型到string,或者直接調(diào)用某個對象的toString()
方法牲平; - 通常不必把任意類型轉(zhuǎn)換為boolean再判斷堤框,因為可以直接寫if (myVar) {...};
- typeof操作符可以判斷出number纵柿、boolean蜈抓、string、function和undefined昂儒;
- 判斷Array要使用
Array.isArray(arr)
沟使; - 判斷null請使用
myVar === null
; - 判斷某個全局變量是否存在用
typeof window.myVar === 'undefined'
渊跋; - 函數(shù)內(nèi)部判斷某個變量是否存在用
typeof myVar === 'undefined'
腊嗡。
任何對象都有toString()方法嗎着倾?null和undefined就沒有!確實如此燕少,這兩個特殊值要除外卡者,雖然null
還偽裝成了object類型。
number對象調(diào)用toString()報SyntaxError:
123.toString(); // SyntaxError
遇到這種情況客们,要特殊處理一下:
123..toString(); // '123', 注意是兩個點虎眨!(123).toString(); // '123'
不要問為什么,這就是JavaScript代碼的樂趣镶摘!
Array中的sort()
如果調(diào)用該方法時沒有使用參數(shù)嗽桩,將按字母順序?qū)?shù)組中的元素進行排序,說得更精確點凄敢,是按照字符編碼的順序進行排序碌冶。要實現(xiàn)這一點,首先應(yīng)把數(shù)組的元素都轉(zhuǎn)換成字符串(如有必要)涝缝,以便進行比較扑庞。
//請?zhí)畛浯a,使mySort()能使傳入的參數(shù)按照從小到大的順序顯示出來拒逮。
function mySort() {
var tags = new Array();//使用數(shù)組作為參數(shù)存儲容器
// 請補充你的代碼
return tags;//返回已經(jīng)排序的數(shù)組
}
var result = mySort(50,11,16,32,24,99,57,100);/傳入?yún)?shù)個數(shù)不確定
console.info(result);//顯示結(jié)果
如果只是簡單的添加了這句
tags = [].slice.call(arguments).sort();
輸出的結(jié)果為[100, 11, 16, 24, 32, 50, 57, 99]
罐氨,100居然排在了最前面,因為sort默認是按照字符編碼的順序進行排序的滩援。
如果想按照其他標(biāo)準(zhǔn)進行排序栅隐,就需要提供比較函數(shù),該函數(shù)要比較兩個值玩徊,然后返回一個用于說明這兩個值的相對順序的數(shù)字租悄。比較函數(shù)應(yīng)該具有兩個參數(shù) a 和 b,其返回值如下:
若 a 小于 b恩袱,在排序后的數(shù)組中** a 應(yīng)該出現(xiàn)在 b 之前泣棋,則返回一個小于 0 的值**。
若 a 等于 b畔塔,則返回 0潭辈。
若 a 大于 b,則返回一個大于 0 的值澈吨。
//正確代碼
tags = Array.prototype.slice.call(arguments);
tags.sort(function(a,b){return a-b;});
升序:則參數(shù)方程返回小于0把敢;降序:則返回值大于0;
js跨域
http://www.cnblogs.com/2050/p/3191744.html
事件代理
//兼容瀏覽器版本差異
function addEvent(element, event, listener) {
if (element.addEventListener) {
element.addEventListener(event, listener, false);
}
else if (element.attachEvent) {
element.attachEvent("on" + event, listener);
}
else {
element["on" + event] = listener;
}
}
//事件代理
function delegateEvent (element, tag, eventName, listener){
addEvent(element, eventName, function(e){
//這里的參數(shù)e就是前面那個event參數(shù)的對象棚辽,自動傳入
e = e || window.event;
var target = e.target || e.srcElement;
console.log("event", e);
//event: click { target: <button>, buttons: 0, clientX: 148, clientY: 124, layerX: 148, layerY: 124 }
console.log("target", target);
//target: <button>
console.log("targetType", typeof target);
//targetType: object
console.log("targetName", target.nodeName);
//targetName: BUTTON
if(target.nodeName.toLowerCase() == tag.toLowerCase()){
listener.call(target, e)
}
})
}
window.onload = function () {
// 在這下面給add-btn綁定一個點擊事件技竟,點擊時觸發(fā)addBtnHandle函數(shù)
var btn = document.getElementById("add-btn");
addEvent(btn, "click", addBtnHandle);
var table = document.getElementById("aqi-table");
// 想辦法給aqi-table中的所有刪除按鈕綁定事件,觸發(fā)delBtnHandle函數(shù)
delegateEvent( table, "button", "click", delBtnHandle);
}