js之重载
在面向?qū)ο笳Z(yǔ)言中,?重載就是一組具有相同名字、不同參數(shù)列表的函數(shù),但在js中,重載的實(shí)現(xiàn)不能像js一樣那么簡(jiǎn)單,因?yàn)閖s名字相同的函數(shù)會(huì)相互覆蓋,這樣只能輸出最后一個(gè)同名函數(shù),哪怕參數(shù)不一樣,那我們?cè)鯓硬拍茏龅街剌d呢,
首先我們可以利用js的函數(shù)中一個(gè)參數(shù),arguments,該參數(shù)有個(gè)屬性,length, 根據(jù)參數(shù)組的長(zhǎng)度不同,我們可以做出相應(yīng)的動(dòng)作,從而達(dá)到重載的目的
function add(){var len = arguments.length; var a = arguments[0];var b = arguments[1];var c = arguments[2];switch(len){case 1:console.log(a);break;case 2:console.log(a+b);break;case 3:console.log(a+b+c);break; default:break;}}add(1); //1add(1,2); //3add(1,2,3); // 6如上面的代碼,如果我們將add 函數(shù)傳進(jìn)來(lái)的參數(shù)進(jìn)行判斷,如果與條件相符,我們就做出相應(yīng)的動(dòng)作,這種方法通俗易懂,如果以后面試問(wèn)道重載可以回答一下,但這樣代碼的利用性太低,多個(gè)函數(shù)需要重復(fù)多次,我們下面講一個(gè)JQuery之父John Resig寫(xiě)的重載
function addMethod(object, name, fn) {var old = object[name]; object[name] = function() {console.log(arguments);console.log(fn.length);if(fn.length === arguments.length) {return fn.apply(this, arguments);} else if(typeof old === "function") {return old.apply(this, arguments);}}console.log(object[name]);}這是一個(gè)關(guān)鍵的方法,他有三個(gè)參數(shù),第一個(gè)是指定的對(duì)象,第二個(gè)是指定對(duì)象要重載的方法,第三個(gè)是實(shí)際重載方法中要執(zhí)行的方法,這樣說(shuō)有點(diǎn)繞口,下面來(lái)看代碼
var people = {values: ["Dean Edwards", "Alex Russell", "Dean Tom"]};addMethod(people, "find", function() {return this.values;});// 這里進(jìn)行第一次函數(shù)綁定,對(duì)people這個(gè)對(duì)象進(jìn)行綁定find函數(shù),我們根據(jù)上面的代碼可知,此時(shí)的old 為undefined
此時(shí)的people.find()被構(gòu)造成一下函數(shù)
function() { console.log(arguments);console.log(fn.length);if(fn.length === arguments.length) {return fn.apply(this, arguments);} else if(typeof old === "function") {return old.apply(this, arguments); } }
?然后我們進(jìn)行第二次綁定
addMethod(people, "find", function(firstName) {var ret = [];for(var i = 0; i < this.values.length; i++) {if(this.values[i].indexOf(firstName) === 0) {ret.push(this.values[i]);}}return ret;});此時(shí)進(jìn)行綁定時(shí),old 變量這時(shí)候就變?yōu)榱说谝粋€(gè)people.find();函數(shù),那么下次被調(diào)用時(shí),第一個(gè)addMethod所綁定的people.find()函數(shù)就會(huì)存在內(nèi)存中,這里巧妙的利用了閉包,將三個(gè)find函數(shù)保存在不同的內(nèi)存空間中,其中的old變量會(huì)指向上一個(gè)的people.find函數(shù)
從而,一直往上訪問(wèn),知道訪問(wèn)到第一個(gè)的old ,下面是完整的代碼。
function addMethod(object, name, fn) {var old = object[name]; object[name] = function() {console.log(arguments);console.log(fn.length);if(fn.length === arguments.length) {return fn.apply(this, arguments);} else if(typeof old === "function") {return old.apply(this, arguments);}}console.log(object[name]);}var people = {values: ["Dean Edwards", "Alex Russell", "Dean Tom"]};/* 下面開(kāi)始通過(guò)addMethod來(lái)實(shí)現(xiàn)對(duì)people.find方法的重載 */// 不傳參數(shù)時(shí),返回peopld.values里面的所有元素addMethod(people, "find", function() {return this.values;});// 傳一個(gè)參數(shù)時(shí),按first-name的匹配進(jìn)行返回addMethod(people, "find", function(firstName) {var ret = [];for(var i = 0; i < this.values.length; i++) {if(this.values[i].indexOf(firstName) === 0) {ret.push(this.values[i]);}}return ret;});// 傳兩個(gè)參數(shù)時(shí),返回first-name和last-name都匹配的元素addMethod(people, "find", function(firstName, lastName) {var ret = [];for(var i = 0; i < this.values.length; i++) {if(this.values[i] === (firstName + " " + lastName)) {ret.push(this.values[i]);}}return ret;});// 測(cè)試:console.log(people.find()); //["Dean Edwards", "Alex Russell", "Dean Tom"]console.log(people.find("Dean")); //["Dean Edwards", "Dean Tom"]console.log(people.find("Dean","Edwards")); //["Dean Edwards"]*/當(dāng)我們調(diào)用people.find();時(shí)會(huì)首先在addMethod所綁定的第三個(gè)people.find()中尋找,此時(shí),fn.length就是期望函數(shù)的參數(shù),而arguments.length是我們調(diào)用函數(shù)的參數(shù),第一個(gè)調(diào)用函數(shù)的參數(shù)為0;而第三個(gè)所綁定的find函數(shù)參數(shù)為2個(gè),所以不相等,我們就會(huì)向上找
old的所指向的第二個(gè)綁定函數(shù),以此類(lèi)推,直到找到與之相匹配的,然后就用apply函數(shù)改變調(diào)用函數(shù)的上下文,并且傳入相關(guān)參數(shù)進(jìn)行輸出。
轉(zhuǎn)載于:https://www.cnblogs.com/maoxiaodun/p/10021609.html
總結(jié)
- 上一篇: Qt Creator快捷键
- 下一篇: webpack钩子调用shell笔记