DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> 這段js代碼得節約你多少時間
這段js代碼得節約你多少時間
編輯:關於JavaScript     
1.應用案例:
復制代碼 代碼如下:
var Mouse = function () {
// Look! no that = this!
this.position = [0, 0];
if (document.addEventListener) {
document.addEventListener('mousemove', ?); //this.move?
} else if (document.attachEvent) {
document.attachEvent("onmousemove", ?); //this.move?怎麼放進去
}
};
Mouse.prototype.move = function (arg1,arg2,event) {
event = window.event || event;
var x = event.pageX || event.offsetX,
y = event.pageY || event.offsetY;
this.position = position = [x, y];
this.log(arg1,arg2);
};
Mouse.prototype.log = function (arg1, arg2) {
console.log(arg1+","+arg2);
console.log(this.position);
};
new Mouse();

上面你知道'?'號那裡要干嘛了嗎?我想給document的mousemove綁定我的move方法,但是遇到難題了,這樣的話,Mouse.prototype.move
裡的this就不會指向Mouse的對象,相信大家經常碰到這種問題.也許你早知道了怎麼解決,但是有更快更簡單的方法嗎?答案是:
Function.prototype.bind()這個神奇的玩意,但是ie6 7 8都不支持,一般現代浏覽器都支持了,我們接下來要做的就是模仿他,
這麼好的方法當然要模仿它,怎麼模仿見下面nothing的原創方法
復制代碼 代碼如下:
(function () {
var proxy = function (fn, target) {
var proxy = function () {
if (2 < arguments.length) { //存在被代理的函數有參數的時候
var privateArgs = Array.prototype.slice.call(arguments, 2);
//從第二個開始取出來,[this,綁定的對象,參數列表]
return function () {
var args = Array.prototype.slice.call(arguments);
-->這裡的arguments與外面的不是同一個,這個是被代理的函數內部的arguments對象,
比如這裡的move函數的 arguments[0]=[object Event]就是這個事件內部的e參數
Array.prototype.unshift.apply(args, privateArgs);
-->這裡在加上傳進來的參數,就實現了,和原生bind一樣的參數形式
//->而且這裡是把私有的參數放到前面的比如a=new Mouse();a.move(1,2);
//如果這個move方法沒有參數,意思就是prototype.move=fn(){arguments} ,
//而我傳進來了參數,參數的arguments.length=3,
//arguments[0]=1,arguments[1]=2,arguments[2]=[object event].
return fn.apply(target, args);
}
//這裡之所以搞復雜了,是因為,在被代理的函數可以直接訪問arguments,比如我不給被代理的函數傳參數,而直接使用
//這樣這個arguments就會包含與原生Function.prototype.bind的arguments一樣的對象,
//這裡代碼深奧,是因為你沒理解這裡原生的bind裡面的arguments是什麼,知道了,就知道為什麼綁定我自己的arguments
//做這麼多,主要目的就是使你被代理的函數內部的arguments與function.prototype.bind裡的arguments對象包含的東西一致
}
return function () {
return fn.apply(target, arguments);
}
}
return proxy.apply(null, arguments);
};
/*支持原生的使用原生的*/
Function.prototype.bind = Function.prototype.bind ||
function (target) { //這裡的this指代要被代理的函數
if (1 < arguments.length) {
var args = Array.prototype.slice.call(arguments, 1); //取出參數列表
args.unshift(this, target); //這個args最終變成了[this,綁定的對象,參數列表]
return proxy.apply(null, args);
--如果直接proxy(args),麻煩來了,args成了proxy函數的一個參數,就會報錯,
其實這裡主要是分開任務處理,proxy只關心代理和參數是怎麼傳給proxy,如果被代理的沒參數,直接;
return proxy(this, target)--> return fn.apply(target, arguments); 就是17樓的那個答案
-->估計大家會跟17樓犯一樣的錯誤,這裡之所以這麼復雜的操作arguments對象,只是為了能保證傳進proxy函數中,保證arguments對象不失效
}
return proxy(this, target);
};
})();

以上代碼為什麼我要一直return回來代理,因為這樣你才能這樣調用this.move.bind(this,1,2)()然後這裡會立即執行函數!
有了以上代碼,我們就可以輕松的實現了"?"號這裡要寫什麼代碼了,^_^,簡單吧
復制代碼 代碼如下:
if (document.addEventListener) {
document.addEventListener('mousemove', this.move.bind(this,1,2));
} else if (document.attachEvent) {
document.attachEvent("onmousemove", this.move.bind(this,1,2));
}

是不是以後凡是碰到要添加事件,然後調用的方法的this又想指向其他對象,這樣是不是很簡單呢..
看到大家對以上代碼有點難理解,來個簡單點得
復制代碼 代碼如下:
var a = function () {
console.log(arguments[0]); //1
console.log(arguments[1]); //2
console.log(this.key1);
//這樣綁定參數的話,我的參數列出來才能和原生的bind一樣,就這麼簡單,
};
var b = {
key1: "value1"
};
a.bind(b, 1, 2)();

反駁17樓同學的代碼錯誤,我想這是很多人會犯的錯誤,代碼如下
復制代碼 代碼如下:
Function.prototype.bind = function (target) {
var self = this;
return function () {
return self.apply(target, arguments); //這裡的arguments根本傳不進來
}
}
var a = function () {
console.log(arguments.length); //這樣bind的話,arguments參數失效
//arguments.length=0.
console.log(this.key1);
};
var b = {
key1: "value1"
};
a.bind(b, [1, 2], 3)(); //從這裡可以看出,期望的arguments.length=2
//這也是我為什麼苦口婆心的操作arguments參數
//我知道這裡大部分人都會覺得對的,但是你錯了,17樓的同學你還得在思考下

不帶注釋的源碼,
復制代碼 代碼如下:
(function () {
var proxy = function (fn, target) {
var proxy = function () {
if (2 < arguments.length) {
var privateArgs = Array.prototype.slice.call(arguments, 2);
return function () {
var args = Array.prototype.slice.call(arguments);
Array.prototype.unshift.apply(args,privateArgs);
return fn.apply(target, args);
}
}
return function () {
return fn.apply(target, arguments);
}
}
return proxy.apply(null, arguments);
};
/*支持原生的使用原生的*/
Function.prototype.bind = Function.prototype.bind ||
function (target) {
if (1 < arguments.length) {
var args = Array.prototype.slice.call(arguments, 1);
args.unshift(this, target);
return proxy.apply(null, args);
}
return proxy(this, target);
};
})();



這篇文章是接著上篇文章講得,我這個講個詳細的列子,如果沒看就點
先看列子,本博客沒時間去搞華麗的布局,只求樸實的代碼,只為js代碼愛好者使用
復制代碼 代碼如下:
var Mouse = function () {
if (document.addEventListener) {
document.addEventListener('mousemove', this.move.bind(this,1,2,[3,4]));
} else if (document.attachEvent) {
document.attachEvent("onmousemove", this.move.bind(this,1,2,[3,4]));
}
};
Mouse.prototype.move = function () {
console.log(arguments[arguments.length-1].clientX);
};

這裡的arguments的輸出結果很好的解釋了上文代碼,不懂得請結合新給出得列子配合理解.
復制代碼 代碼如下:
var privateArgs = Array.prototype.slice.call(arguments, 2);
//私有的參數,表示代理者的參數,這裡代表1,2,[3,4]
return function () {
var args = Array.prototype.slice.call(arguments);
//這裡的參數,代表被代理者的參數,這裡如事件函數內部的e
Array.prototype.unshift.apply(args, privateArgs);
//這裡是將兩者的參數合並在一起,然後私有參數在前,目的也是為了和原生的參數順序一致
return fn.apply(target, args);
//將合並後的參數這裡包括1,2,[3,4] e傳進去,並apply
}

好,到了這裡,你會發現一個不錯的js技巧,就是不用兼容處理e=window.event||e,直接使用arguments[arguments.length-1]就能兼容代表
所有浏覽器的事件e對象,節省了不少的代碼與思考的時間,
之所以寫出這段代碼,是希望大家對js代碼有個真正的理解,知道js的真正魅力在哪裡,如果了真看懂了此文,至少你知道了arguments到底是
怎麼回事了,本博客破爛無比,只有樸實的代碼,適合js代碼愛好者學習.
其實真正的js魅力何止這點.有了以上的實例加上說明,相信你也應該了解得差不多了,不懂得多demo幾下就知道了.
一個js愛好者,會時不時貼出一些較為新鮮的代碼供大家學習,本博客的目的就是為了共同學習js代碼的精髓.
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved