博客
关于我
手写bind_中高级前端面试JavaScript手写代码无敌秘籍
阅读量:367 次
发布时间:2019-03-05

本文共 6844 字,大约阅读时间需要 22 分钟。

深圳内推:前端开发岗位

目前本人正在寻找深圳地区的前端开发岗位,欢迎各位大佬和HR小姐姐内推靠谱的工作机会!不拘泥于996ICU这样的标签,希望能找到一个和自己发展方向匹配的团队!

技术分享

1. new操作符

new操作符在JavaScript中扮演着重要角色。它不仅创建了一个全新的对象,还会将这个对象的[[Prototype]](即__proto__)链接到函数的prototype对象上。这意味着新对象会继承函数的属性和方法。

function New(func) {    var res = {};    if (func.prototype !== null) {        res.__proto__ = func.prototype;    }    var ret = func.apply(res, Array.prototype.slice.call(arguments, 1));    if ((typeof ret === "object" || typeof ret === "function") && ret !== null) {        return ret;    }    return res;}var obj = New(A, 1, 2); // 等同于 var obj = new A(1, 2);

2. JSON.stringify

JSON.stringify是一个将JavaScript对象序列化为JSON字符串的函数,支持对嵌套对象的处理,忽略循环引用和非可枚举属性。

function jsonStringify(obj) {    let type = typeof obj;    if (type !== "object" || type === null) {        if (/string|undefined|function/.test(type)) {            obj = '"' + obj + '"';        }        return String(obj);    } else {        let json = [];        arr = (obj && obj.constructor === Array) ? true : false;        for (let k in obj) {            let v = obj[k];            let type = typeof v;            if (/string|undefined|function/.test(type)) {                v = '"' + v + '"';            } else if (type === "object") {                v = jsonStringify(v);            }            json.push((arr ? "" : '"' + k + '":') + String(v));        }        return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");    }}

3. JSON.parse

JSON.parse将JSON字符串解析为JavaScript对象或数组。可以通过reviver函数对解析后的对象进行处理。

4. call和apply

callapply方法允许指定一个this值并传递参数给函数。call接受多个参数,而apply接受参数数组。

Function.prototype.call2 = function(content = window) {    content.fn = this;    let args = [...arguments].slice(1);    let result = content.fn(...args);    delete content.fn;    return result;}Function.prototype.apply2 = function(context = window) {    context.fn = this;    let result;    if (arguments[1]) {        result = context.fn(...arguments[1]);    } else {        result = context.fn();    }    delete context.fn;    return result;}

5. Function.bind

Function.bind方法用于绑定函数上下文,即指定this值,之后的参数会在传递给函数时作为实际参数。

Function.prototype.bind2 = function(content) {    if (typeof this !== "function") {        throw Error("not a function");    }    let fn = this;    let args = [...arguments].slice(1);    let resFn = function() {        return fn.apply(this instanceof resFn ? this : content, args.concat(...arguments));    };    tmp.prototype = this.prototype;    resFn.prototype = new tmp();    return resFn;}

6. 继承

实现一个寄生组合式继承,避免多次调用父类构造函数。

function Parent(name) {    this.name = name;}Parent.prototype.sayName = function() {    console.log('parent name:', this.name);};function Child(name, parentName) {    Parent.call(this, parentName);    this.name = name;}function create(proto) {    function F() {}    F.prototype = proto;    return new F();}Child.prototype = create(Parent.prototype);Child.prototype.constructor = Child;

7. 函数柯里化

柯里化将多参数函数转换为接受一个参数并返回一个新函数的形式。

function curry(fn) {    var args = Array.prototype.slice.call(arguments);    var fn = function() {        var newArgs = args.concat(Array.prototype.slice.call(arguments));        return fn.apply(this, newArgs);    };    fn.toString = function() {        return args.reduce(function(a, b) {            return a * b;        }, 1);    };    return fn;}const curry = (fn, arr = []) => (...args) => {    if (arg.length === fn.length) return fn(...arg);    return curry(fn, arr.concat(...args));};// 示例const multiFn = curry(multiFn);multi(2)(3)(4); // 2 * 3 * 4 = 24

8. Promise

实现一个符合Promise/A+规范的Promise,支持thencatch方法。

const PENDING = "pending";const FULFILLED = "fulfilled";const REJECTED = "rejected";function myPromise(executor) {    let self = this;    self.status = PENDING;    self.value = undefined;    self.reason = undefined;    self.onFulfilledCallbacks = [];    self.onRejectedCallbacks = [];    function resolve(value) {        if (self.status === PENDING) {            self.status = FULFILLED;            self.value = value;            self.onFulfilledCallbacks.forEach(cb => cb(self.value));        }    }    function reject(reason) {        if (self.status === PENDING) {            self.status = REJECTED;            self.reason = reason;            self.onRejectedCallbacks.forEach(cb => cb(self.reason));        }    }    try {        executor(resolve, reject);    } catch (e) {        reject(e);    }    return {        then(onFulfilled, onRejected) {            const that = this;            let newPromise = new Promise((resolve, reject) => {                setTimeout(() => {                    try {                        let x = onFulfilled ? onFulfilled(that.value) : that.value;                        resolve(x);                    } catch (e) {                        reject(e);                    }                }, 0);            });            return newPromise;        },        catch(onRejected) {            const that = this;            let newPromise = new Promise((resolve, reject) => {                setTimeout(() => {                    try {                        let x = onRejected ? onRejected(that.reason) : that.reason;                        resolve(x);                    } catch (e) {                        reject(e);                    }                }, 0);            });            return newPromise;        }    };}

9. 防抖和节流

防抖:限制事件处理的频率,避免多次调用同一函数。

function debounce(fn, wait = 50, immediate = true) {    let timer;    return function() {        if (immediate) {            fn.apply(this, arguments);        }        if (timer) clearTimeout(timer);        timer = setTimeout(() => {            fn.apply(this, arguments);        }, wait);    };}// 示例function handleScroll() {    console.log('scroll');}const debouncedHandleScroll = debounce(handleScroll, 500);window.addEventListener('scroll', debouncedHandleScroll);

节流:限制事件处理的频率,确保在一定时间内只调用一次。

function throttle(fn, wait) {    let lastCall = 0;    return function(...args) {        const now = Date.now();        if (now - lastCall > wait) {            fn.apply(this, args);            lastCall = now;        }    };}// 示例function handleResize() {    console.log('resize');}const throttledHandleResize = throttle(handleResize, 500);window.addEventListener('resize', throttledHandleResize);

10. 深拷贝

实现深拷贝,适用于复杂数据结构。

function deepCopy(obj) {    if (typeof obj !== "object") {        return obj;    }    let result = obj.constructor === Array ? [] : {};    for (let key in obj) {        result[key] = typeof obj[key] === "object" ? deepCopy(obj[key]) : obj[key];    }    return result;}

11. instanceOf

判断对象是否是另一个对象的实例。

function instanceOf(left, right) {    let proto = left.__proto__;    let prototype = right.prototype;    while (true) {        if (proto === null) return false;        if (proto === prototype) return true;        proto = proto.__proto__;    }}

如果你或你的团队有合适的内推信息,欢迎随时联系!微信:huab119,邮箱:454274033@qq.com

转载地址:http://ejjg.baihongyu.com/

你可能感兴趣的文章
Objective-C实现rayleigh quotient瑞利商算法(附完整源码)
查看>>
Objective-C实现RC4加解密算法(附完整源码)
查看>>
Objective-C实现recursive bubble sor递归冒泡排序算法(附完整源码)
查看>>
Objective-C实现recursive insertion sort递归插入排序算法(附完整源码)
查看>>
Objective-C实现recursive quick sort递归快速排序算法(附完整源码)
查看>>
Objective-C实现RedBlackTree红黑树算法(附完整源码)
查看>>
Objective-C实现redis分布式锁(附完整源码)
查看>>
Objective-C实现reverse letters反向字母算法(附完整源码)
查看>>
Objective-C实现ripple adder涟波加法器算法(附完整源码)
查看>>
Objective-C实现RodCutting棒材切割最大利润算法(附完整源码)
查看>>
Objective-C实现Romberg算法(附完整源码)
查看>>
Objective-C实现round robin循环赛算法(附完整源码)
查看>>
Objective-C实现RRT路径搜索(附完整源码)
查看>>
Objective-C实现rsa 密钥生成器算法(附完整源码)
查看>>
Objective-C实现RSA密码算法(附完整源码)
查看>>
Objective-C实现RSA素因子算法(附完整源码)
查看>>
Objective-C实现runge kutta龙格-库塔法算法(附完整源码)
查看>>
Objective-C实现segment tree段树算法(附完整源码)
查看>>
Objective-C实现segmented sieve分段筛算法(附完整源码)
查看>>
Objective-C实现selection sort选择排序算法(附完整源码)
查看>>