call
Function.prototype.myCall = function () {
//获取this指向
var _this = arguments[0];
//兼容this指向为原始值
if (typeof _this == 'number') {
_this = new Number(_this)
} else if (typeof _this == 'boolean') {
_this = new Boolean(_this)
} else if (typeof _this == 'string') {
_this = new String(_this)
} else if (!_this) {
//兼容浏览器和node
try {
_this = window;
} catch (e) {
_this = {};
}
}
// 获取参数
var _arguments = [...arguments].slice(1);
//挂载到this指向上面
_this.fn = this;
//使用eval执行这个新增的方法
var result = eval('_this.fn(' + [..._arguments].join(',') + ')');
//删除该方法
delete _this.fn;
//返回执行结果
return result;
}
复制代码
apply
Function.prototype.myCall = function (_this, arr) {
_this = _this;
if (typeof _this == 'number') {
_this = new Number(_this)
} else if (typeof _this == 'boolean') {
_this = new Boolean(_this)
} else if (typeof _this == 'string') {
_this = new String(_this)
} else if (!_this) {
try {
_this = window;
} catch (e) {
_this = {};
}
}
_this.fn = this;
if (!arr) {
var result = ctx.fn();
} else {
var result = eval('_this.fn(' + [...arr].toString() + ')');
}
delete _this.fn;
return result;
}
复制代码
bind
Function.prototype.myBind = function (target) {
var self = this;
//获取参数
var args = [].slice.call(arguments, 1);
var fn = function () {
var _arg = [].slice.call(arguments, 0);
return self.apply(target, args.concat(_arg));
}
// 设置返回的新函数的函数的原型链
fn.prototype.__proto__ = this.prototype
return fn;
}
复制代码
节流
function throttle(fn, delay) {
var lock = false;
return function () {
if (!lock) {
fn(...arguments);
lock = true;
setTimeout(() => {
lock = false;
}, delay);
}
}
}
复制代码
防抖
function debounce(fn, delay) {
var lock = false;
var timer = null;
return function () {
if (!lock) { //开锁状态下
fn(...arguments);
lock = true;
timer = setTimeout(() => {
lock = false;
}, delay);
} else { //锁启用状态下
clearInterval(timer);
timer = setTimeout(() => {
lock = false;
}, delay);
}
}
}
复制代码
单层柯里化
//传入想要进行柯里化处理的函数和前几个参数
function fixedParam(fn) {
var _arguments1 = [].slice.call(arguments, 1);
return function () {
var _arguments2 = [...arguments];
fn.apply(this, [..._arguments1, ..._arguments2]);
}
}
function sum(a, b, c, d) {
console.log(a + b + c + d);
}
//
var currySum = fixedParam(sum, 1, 2);
//下次执行输入剩下的参数
currySum(3, 4);
复制代码
多层柯里化1 (理解起来较难,比较绕)
function fixedParam(fn) {
var _arguments1 = [].slice.call(arguments, 1);
return function () {
var _arguments2 = [...arguments];
fn.apply(this, [..._arguments1, ..._arguments2]);
}
}
function Curry(fn, length) {
var len = length || fn.length;
//采用闭包思想,第一次读取参数总长度,
return function () {
console.log(arguments);
//每一次的参数都是独立的
if (arguments.length < len) {
//当参数长度不足的时候,执行fixedParam,
var combineArguments = [fn].concat(...arguments);
// 参数会存入到fixedParam的AO的_arguments中
var fixedFn = fixedParam.apply(this, combineArguments);
// 还须要多少参数才能执行
var needParams = len - arguments.length;
// 递归返回函数
return Curry(fixedFn, needParams);
} else {
//已经知足执行条件,执行
return fn.apply(this, arguments);
}
}
}
function sum(a, b, c, d) {
console.log(a + b + c + d);
}
var currySum = Curry(sum);
currySum(1)(2)(3)(4);
//argumnets 打印结果
/*
[Arguments] { '0': 1 }
[Arguments] { '0': 2 }
[Arguments] { '0': 3 }
[Arguments] { '0': 4 }
*/
复制代码
多层柯里化2 (这种方式理解更容易些)
(function () {
try {
_this = window;
} catch (e) {
_this = this;
}
//兼容浏览器和node后端
_this.Curry = Curry;
//导出Curry方法
//函数主体部分
var _arguments = [];
//参数列表
function Curry(fn, length) {
var len = length || fn.length;
console.log(_arguments)
return function () {
_arguments = _arguments.concat([...arguments]);
if (arguments.length < len) {
return Curry(fn, len - arguments.length);
} else {
return fn.apply(this, _arguments);
}
}
}
})()
function sum(a, b, c, d) {
console.log(a + b + c + d);
}
var currySum = Curry(sum);
currySum(1, 2, 3)(4);
复制代码
惰性函数处理事件绑定兼容ie8和w3c.
<body>
<button id="button1"></button>
<button id="button2"></button>
<script>
var oBtn1 = document.getElementById('button1');
var oBtn2 = document.getElementById('button2');
Element.prototype.addEvent = function (type, handle) {
if (this.addEventListener) {
this.addEventListener(type, handle);
Element.prototype.addEvent = function (type, handle) {
console.log('您的浏览器是符合W3C标准的');
this.addEventListener(type, handle, false);
}
} else {
//兼容 ie8
this.attachEvent('on' + type, handle);
Element.prototype.addEvent = function (type, handle) {
console.log('您的浏览器是不符合W3C标准的');
this.attachEvent('on' + type, handle)
}
}
}
oBtn1.addEvent('click', function () {
console.log(this)
})
oBtn2.addEvent('click', function () {
console.log(this)
})
</script>
</body>
复制代码
记忆函数
function memorize(fn) {
var cache = {};
return function () {
var key = arguments.length + '-' + Array.prototype.join.call(arguments, '-');
if (cache[key]) {
return cache[key];
} else {
return cache[key] = fn.apply(this, arguments);
}
}
}
function addToOne(n) {
if (n == 1) return 1;
return n + addToOne(n - 1);
}
var memorizeAddToOne = memorize(addToOne);
console.log(memorizeAddToOne(100));
复制代码