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);
			}
		}
	}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值