快速排序、函数柯里化、call封装bind,编程大杂烩

这是一篇杂乱的编程题练习

call封装一个bind
先说下call,apply,bind干嘛用的:
他们都是用来改变this指向的,call,apply只是传的参数方式不同,并且是立即执行,返回一个值。bind()则返回的是一个函数,需要触发才可以执行,bind的好处是可以把转变this指向的功能封装成函数,方便复用。
语法:

call(context,arg1,arg2…)
context是this对象,context==null || context == undefined
context === window
apply(context,[arg1,arg2…])

	eg1 一个例子来看call和apply的区别:
	var arr = [3,4,2];
	var maxCall = Math.max.call(null,arr[0],arr[1],arr[2]);
	var maxApply = Math.max.apple(null,arr);

	eg2 一个例子来看绑定的this值和参数的使用场景。
	var obj = {
		msg : "hello"
	}
	function fn(firstName,lastName) {
		return this.msg + firstName + lastName;
	}
	fn.call(obj,'hu','ting');
	eg3 一个例子看bind的使用
	var obj = {
		msg : "hello"
	}
	function fn(firstName,lastName) {
		return this.msg + firstName + lastName;
	}
	var fnBind = fn.bind(obj,['hu','ting']);
	console.log(fnBind);
	
	eg4 bind参数的使用
	function fn(a, b, c) {
	    console.log(a, b, c);
	}
	var fn1 = fn.bind(null, 'Dot');
	
	fn('A', 'B', 'C');            // A B C
	fn1('A', 'B', 'C');           // Dot A B
	fn1('B', 'C');                // Dot B C
	fn.call(null, 'Dot');      // Dot undefined undefined
	call 是把第二个及以后的参数作为 fn 方法的实参传进去,
	而fn1方法的实参实则是在 bind 中参数的基础上再往后排。

	eg4 有些浏览器没有bind方法,用call实现一个bind;
	function bind() {
		if(!Function.prototype.bind) {
			Function.prototype.bind = function () {
				var self = this,
					context = [].shift.call(arguments),//保存上下文;
					arg = [].slice.call(arguments);//保存参数;
				return self.apply(context, [].concat.call(arg,[].slice.call(arguments)));
			}
		}
	}
	

bind、call、apply的常用场景

eg1 将类数组转化成数组
[].prototype.slice.apply(arrayLike);
eg2 数组追加
var a1 = [1,2,3];
var a2 = [4,5,6];
var a3 = a1.push.apply(a1,a2);
eg3 判断类型
function isArray(obj) {
	return Object.prototype.toSting.call(obj) == ['Object','Array'];
	//[].prototype.toString() == ['Object','Array'];
}
eg4 利用call和apply做继承
function Person(name,age) {
	this.name = name;
	this.age = age;
	this.sayName = function() {
		console.log(this.name);
	}
}
function female() {
	Person.apply(this,arguments);
}
var p = new female('hyt');
p.sayName();

快速排序
1、以中间数为基准;
2、遍历数组,比基准小的放左边,比基准大的放右边;
3、递归函数执行第二步,直至区间只剩一个数;

function sort(arr){
	var mid = Math.floor(arr.length/2);//找到中间的数作为基准;
	var left = [];
	var right = [];
	var midVal = arr.splice(mid,1);//删除数组中间数,并把中间数赋值给midVal;
	if (arr.length <= 1) {
		return arr;
	}
	for (var i = 0; i < arr.length; i++) {
		if (arr[i] < midVal) {
			left.push(arr[i]);
		} else {
			right.push(arr[i]);
		}
	}
	//递归执行第二步;
	return sort(left).concat(midVal,sort(right));
}
var arr1 = [1,3,6,8,4,9,0,2];
sort(arr1);

函数柯里化

柯里化的作用
事件绑定的时候检测应该用dom几的方式,柯里化的话,只需要检测一次,返回一个新的函数来进行事件绑定(我觉得所有需要判断的地方,如果判断条件在一次访问中不改变的话,都可以写成柯里化的形式,从而达到只进行一次判断的效果)
利用柯里化的思想,可以自己写一个bind函数,延迟执行某个函数,(在一些文章中看到回调函数可以借助这个,还不是很理解,有待之后补充)

函数防抖和call封装bind,有什么联系吗?为什么两个考题经常一起出现啊?
想不明白为啥call封装bind,函数防抖两个问题总是一起出现,看代码共同处都用到了apply,转换this指向。它们和curry又有什么联系吗?还是说我应该研究一下apply转换this指向都有哪些具体的场景呢?
咖啡厅要关门了,今天就简单写到这儿吧!

function debounce(fn,delay) {
	var last;
	return function() {
		var context = this;
		clearTimeout(last);
		setTimeout(() => {
			return fn.apply(context,arguments);
		},delay);
	}
}

去除数组中的item元素,返回一个新数组。

function remove(array,item) {
	var arr = [];
	for(var i = 0; i < array.length; i++) {
		if(array[i] !== item) {
			arr.push(array[i]);
		}
	}
	return arr;
}
remove([1,1,2,3,4],3);

reduce(有时间可以用reduce来实现一个排队发送请求的需求);

arr.reduce(callback[, initialValue])

var arr = [1,2,3,5,4];
arr.reduce((pre,cur) => {
	return pre + cur;
});

slice(slice可以用来复制一个新的数组~)

function remove (arr) {
	var newArr = arr.slice(0);
	//splice方法可以复制一个数组
	for (let i of arr) {
		if(newArr[i] === item) {
			newArr.splice(i,1);
		}
	}
	return newArr;
}
remove([1,2,3,3,4],4);

获取data中所有性别是女的平均年龄 (待完成)

data{
	province: [
		{'湖北' : 
			[
				{'sex': 'male','age': 10},	
				{'sex':'female','age': 20}
			]
		}, 
		{'湖南' : 
			[
				{'sex': 'male','age': 10},
				{'sex':'female','age': 20}
			]
		}
	]
}
var p = data.province;
console.log(p);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值