bind(参考:js中自己实现bind函数的方式)
Function.prototype.myBind=function(){
var self = this, // 保存原函数
context = [].shift.call(arguments), // 保存需要绑定的this上下文
args = [].slice.call(arguments); // 剩余的参数转为数组
return function () { // 返回一个新函数
self.apply(context,[].concat.call(args, [].slice.call(arguments)));
}
}
例子:
function Test(){
console.log(this)
}
function func(){
}
Test(); // window 全局域
Test = Test.myBind(func); // 改变this指向
Test(); // func 作用域
new的实现
function myNew() {
let obj = {}; // 创建一个空的对象
let constructor = [].shift.call(arguments) // 获得构造函数
obj.__proto__ = constructor.prototype; // 链接到原型
let res = constructor.apply(obj,arguments) // 绑定 this,执行构造函数
return res instanceof Object ? result : obj // 确保 new 出来的是个对象
}
例子:
function myNew() {
let obj = {}; // 创建一个空的对象
let constructor = [].shift.call(arguments) // 获得构造函数
obj.__proto__ = constructor.prototype; // 链接到原型
let res = constructor.apply(obj,arguments) // 绑定 this,执行构造函数
return res instanceof Object ? result : obj // 确保 new 出来的是个对象
}
function Test(){
}
let son1 = myNew(Test);
son1.__proto__ === Test.prototype; // true
son1.constructor === Test; // true
son1 instanceof Test; // true
函数防抖
// func是用户传入需要防抖的函数
// wait是等待时间
const debounce = (func, wait = 500) => {
// 这里返回的函数是每次用户实际调用的防抖函数
// 如果已经设定过定时器了就清空上一次的定时器
// 开始一个新的定时器,延迟执行用户传入的方法
let timer = null;
return function() {
if (timer) clearTimeout(timer)
timer = setTimeout(func, wait)
}
}
例子:
const debounce = (func, wait = 500) => {
let timer = null;
return function() {
let that=this;
let args=arguments;
if (timer) clearTimeout(timer)
timer = setTimeout(function(){
func.apply(that,args)
}, wait)
}
}
function handle(){
console.log(Math.random());
}
window.addEventListener("resize",debounce(handle,1000)); // 窗口size改变时打印日志
函数节流
function throttle(func,wait=500){
let timer=null;
return function(){
let that=this;
let args=arguments;
if(timer) return; // 之前的定时器未执行完
timer=setTimeout(function(){
func.apply(that,args);
timer = null;
},wait);
}
}
例子:
function throttle(func,wait=500){
let timer=null;
return function(){
let that=this;
let args=arguments;
if(timer) return; // 之前的定时器未执行完
timer=setTimeout(function(){
func.apply(that,args);
timer = null;
},wait);
}
}
function handle(){
console.log(Math.random());
}
window.addEventListener("resize",throttle(handle,1000)); // 窗口size改变时打印日志
深拷贝
function deepClone(obj) {
let result = typeof obj.splice === "function" ? [] : {};
if (obj && typeof obj === 'object') {
for (let key in obj) {
if (obj[key] && typeof obj[key] === 'object') {
result[key] = deepClone(obj[key]);//如果对象的属性值为object的时候,递归调用deepClone,即在吧某个值对象复制一份到新的对象的对应值中。
} else {
result[key] = obj[key];//如果对象的属性值不为object的时候,直接复制参数对象的每一个键值到新的对象对应的键值对中。
}
}
return result;
}
return obj;
}
promise
class Promise {
result: any;
callbacks = [];
failbacks = [];
constructor(fn) {
fn(this.resolve.bind(this), this.reject.bind(this));
}
resolve(res) {
if (this.callbacks.length > 0) this.callbacks.shift()(res, this.resolve.bind(this), this.reject.bind(this));
}
reject(res) {
this.callbacks = [];
if (this.failbacks.length > 0) this.failbacks.shift()(res, this.resolve.bind(this), this.reject.bind(this));
}
catch(fn) {
this.failbacks.push(fn);
}
then(fn) {
this.callbacks.push(fn);
return this;
}
}
extends实现
//子类 extends 父类
Function.prototype.extends = function(func, options){
for(var key in func.prototype){
this.prototype[key] = func.prototype[key];
}
for(var name in options){
this.prototype[name] = options[name];
}
}
单例模式
function A(name){
// 如果已存在对应的实例
if(typeof A.instance === 'object'){
return A.instance
}
//否则正常创建实例
this.name = name
// 缓存
A.instance =this
return this
}
发布订阅模式
// 事件类
class EventEmitter {
constructor () {
this.events = { } // 事件队列,保存着每一种事件的处理程序
}
on (type, callback) { // type 要绑定的事件名字, callback 处理程序
if (this.events[type]) {// 如果事件队列中有这个事件
// 将此次绑定的处理程序放入进去
this.events[type].push(callback.bind(this))
return false
}
// 如果没有这个事件,新建
this.events[type] = [callback.bind(this)]
}
emit (type, ...args) {
// 触发事件的时候如果没有事件,报错
if (!this.events[type]) {
console.error('type event is not found')
}else {
// 挨个执行队列中的处理程序
this.events[type].forEach(callback => {
callback(...args)
});
}
}
}
let bus = new EventEmitter()
bus.on('play', (num1, num2) => {
alert(123)
})
bus.on('play', (num1, num2) => {
alert(456)
alert(num1 + num2)
})
bus.emit('play', 1, 2)