js高級函數的認識

來自《javascript高級程序設計》

  • 安全類型的檢測

多個iframe存在多個全局作用域,在使用value instanceof  array時,必須與array構造函數在同一個全局作用域並且是一個數組。

Object.toString方法可放回[object nativeconstructorname]格式的字符串。通過這個函數測試某個值是不是原生函數、正則表達式。

function isArray(value){
		return Objet.prototype.toString.call(value) == '[Object Array]';
	}

	function isFunction(value){
		return Object.prototype.toString.call(value)=='[Object Function]'
	}

	function isRegExp(value){
		return Object.prototype.toString.call(value)=='[Object RegExp]'
	}
  • 作用域安全的構造函數

確保構造函數this指向指定對象。

function Person(name){
		if(this instanceof Person){
			this.name=name;
		}else{
			return new Person(name);
		}
	}
	let p1=new Person('p1');
	console.log(window.name,p1.name)
	let p2=Person('p2');
	console.log(p2.name)
	//繼承可能會被破壞,使用原型鏈和寄生組合可解決這個問題
	function Polygon(sides){
		if(this instanceof of Polygon){
			this.sides=sides;
			this.getArea=function(){
				return 0;
			}
		}else{
			return new Polygon(sides);
		}
	}

	function Rectangle(width,height){
		Polygon.call(this,2);
		this.width=width;
		this.height=height;
		this.getArea=function(){
			return this.width*this.height;
		}
	}
	Rectangle.prototype=new Polygon();
	let rect=new Rectangle(5,10);
	console.log(rect.sides)
  • 函數柯里化

用於創建已經設置好了一個或者多個參數的函數。使用閉包返回函數。動態創建:調用另一個函數併爲它傳入要傳柯里化函數和必要參數。


	// 函數柯里化
	// 將返回的函數進行排序。
	function curry(fn){
		var args=Array.prototype.slice.call(arguments,1);
		// arguments並非數組,可通過下標獲取參數,無slice方法
		return function(){
			var innerArgs=Array.prototype.slice.call(arguments);
			var finalArgs=args.concat(innerArgs);
			return fn.apply(null,finalArgs);//執行環境可能被破壞null
		}
	}

	//綁定給定環境
	function bind(fn,context){
		var args=Array.prototype.slice.call(arguments,2);
		return function(){
			var innerArgs=Array.prototype.slice.call(arguments);
			var finalArgs=args.concat(innerArgs);
			return fn.apply(context,finalArgs);
		}
	}
  • 定時器settimeout,setinterval

js是單線程的

在特定的時間後將代碼插入到主隊列,不能保證代碼一定在指定時間後運行。

setinterval:js引擎將處理:當沒有改定時器的任何其他代碼實例時,纔將定時器代碼添加到隊列中,確保定時器代碼加入到隊列的最小時間間隔爲指定間隔。存在缺點:定時器代碼未執行完,又向隊列插入新的定時器代碼。

使用鏈式setTimeout可避免:

//保證在下一次定時器代碼執行之前,至少要等到指定的間隔
	setTimeout(function(){
		//處理代碼
		setTimeout(arguments.callee,interval);
	},interval);
  • yield process

js代碼的長時間運行腳本制約。德朗的任務可通過定時器數組分割array chunking技術。爲要處理的項目創建一個隊列,然後使用定時器去除下一個要處理的項目進行處理,接着再設置另一個定時器。

// 基本模式
	setTimeout(function(){
		var item=array.shift();
		process(item);
		if(array.length>0){
			setTimeout(arguments.callee,100)
		}
	},100);

	function chunk(array,process,context){
		setTimeout(function(){
			var item=array.shift();
			process.call(context,item);
			if(array.length>0){
				setTimeout(arguments.callee,100)
			}
		},100)
	}
	// 函數字節流
	var processor={
		timeroutId:null,
		performProcessing:function(){
			//實際執行的代碼
		},
		process:function(){
			clearTimeout(this.timeroutId);
			var that=this;
			this.timeroutId=setTimeout(function(){
				that.performProcessing();
			},100)
		}

	}
	//執行
	process.process();

	//簡化
	function throttle(method,context){
		clearTimeout(method.tId);
		method.tId=setTimeout(function(){
			method.call(context);
		},100)
	}
	//可引用語window.onresize時更改大量dom元素樣式
  • 自定義事件
//自定義事件--創建一個管理事件的對象,讓其他對象監聽那些事件。

	function EventTarget(){
		this.handlers={}
	}
	EventTarget.prototype={
		constructor:EventTarget,
		addHandler:function(type,handler){
			if(typeof this.handlers[type]=='undefined'){
				this.handlers[type]=[];
			}
			this.handlers[type].push(handler);
		},
		fire:function(event){
			if(!event.target){
				event.target=this;
			}
			if(this.handlers[event.type] instanceof Array){
				var handlers=this.handlers[event.type];
				for(var i=0,len=handlers.length;i<len;i++){
					handlers[i](event);
				}
			}
		},
		removeHandler:function(type,handler){
			if(this.handlers[type] instanceof Array){
				for(var i=0,len=handlers.length;i<len;i++){
					if(handlers[i]==handler){
						break;
					}
				}
				handlers.splice(i,1);
			}
		}
	}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章