lgwebdream / FE-Interview

🔥🔥🔥 前端面试,独有前端面试题详解,前端面试刷题必备,1000+前端面试真题,Html、Css、JavaScript、Vue、React、Node、TypeScript、Webpack、算法、网络与安全、浏览器

Home Page:https://lgwebdream.github.io/FE-Interview/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

第 16 题:实现链式调用

lgwebdream opened this issue · comments

欢迎在下方发表您的优质见解

链式调用的核心就在于调用完的方法将自身实例返回
1)示例一

function Class1() {
    console.log('初始化')
}
Class1.prototype.method = function(param) {
    console.log(param)
    return this
}
let cl = new Class1()
//由于new 在实例化的时候this会指向创建的对象, 所以this.method这个方法会在原型链中找到。
cl.method('第一次调用').method('第二次链式调用').method('第三次链式调用')

2)示例二

var obj = {
    a: function() {
        console.log("a");
        return this;
    },
    b: function() {
        console.log("b");
        return this;
    },
};
obj.a().b();

3)示例三

// 类
class Math {
    constructor(value) {
        this.hasInit = true;
        this.value = value;
        if (!value) {
            this.value = 0;
            this.hasInit = false;
        }
    }
    add() {
        let args = [...arguments]
        let initValue = this.hasInit ? this.value : args.shift()
        const value = args.reduce((prev, curv) => prev + curv, initValue)
        return new Math(value)
    }
    minus() {
        let args = [...arguments]
        let initValue = this.hasInit ? this.value : args.shift()
        const value = args.reduce((prev, curv) => prev - curv, initValue)
        return new Math(value)
    }
    mul() {
        let args = [...arguments]
        let initValue = this.hasInit ? this.value : args.shift()
        const value = args.reduce((prev, curv) => prev * curv, initValue)
        return new Math(value)
    }
    divide() {
        let args = [...arguments]
        let initValue = this.hasInit ? this.value : args.shift()
        const value = args.reduce((prev, curv) => prev / (+curv ? curv : 1), initValue)
        return new Math(value)
    }
}

let test = new Math()
const res = test.add(222, 333, 444).minus(333, 222).mul(3, 3).divide(2, 3)
console.log(res.value)

// 原型链
Number.prototype.add = function() {
    let _that = this
    _that = [...arguments].reduce((prev, curv) => prev + curv, _that)
    return _that
}
Number.prototype.minus = function() {
    let _that = this
    _that = [...arguments].reduce((prev, curv) => prev - curv, _that)
    return _that
}
Number.prototype.mul = function() {
    let _that = this
    _that = [...arguments].reduce((prev, curv) => prev * curv, _that)
    return _that
}
Number.prototype.divide = function() {
    let _that = this
    _that = [...arguments].reduce((prev, curv) => prev / (+curv ? curv : 1), _that)
    return _that
}
let num = 0;
let newNum = num.add(222, 333, 444).minus(333, 222).mul(3, 3).divide(2, 3)
console.log(newNum)

class LinkCall {
constructor(name) {
this.name = name;
}
call(params) {
console.log(params);
this.params = params;
// 核心点在于最后返回实例本身
return this;
}
}
const linkCall = new LinkCall('james');
linkCall.call('call one').call('call two').call('call three');

// call one
// call two
// call three

class Person {
      handle() {
        console.log('先洗手')
        return this
      }
      eat() {
        console.log('在吃饭');
        return this
      }
      drink() {
        console.log('去喝水');
        return this
      }
      say() {
        console.log('聊聊天')
      }
    }
    const person = new Person();
    person.handle().eat().drink().say()
//先洗手 index.html:35 在吃饭 index.html:39 去喝水 index.html:43 聊聊天
var pipe = function (value) {
  let stack = [];
  let proxy = new Proxy(
    {},
    {
      get(target, prop, receiver) {
        if (prop === "get") {
          return stack.reduce((x, fn) => {
            return fn(x);
          }, value);
        }
        stack.push(window[prop]);
        // !关键
        return proxy;
      },
    }
  );
  return proxy;
};

var double = (n) => n * 2;
var pow = (n) => n * n;
var reverseInt = (n) => n.toString().split("").reverse().join("") | 0;

pipe(3).double.pow.reverseInt.get; // 63

链式调用的关键在于返回自身this,便于后面继续调用

class  Calculator {
  constructor(val) {
    this.value = val
  }

  add(val) {
    this.value += val

    return this
  }

  sub(val) {
    this.value -= val

    return this
  }

  mul(val) {
    this.value *= val

    return this
  }

  div(val) {
    this.value /= val

    return this
  }

  toString() {
    return this.value
  }
}

const calculator = new Calculator(2)

console.log(+calculator.add(3).sub(2).mul(10).div(2))
/**
 * 实现链式调用
 * 实例的方法返回实例本身就可以链式调用
 */
// 四则运算类
class ASMD {
  constructor(value) {
    this.value = value;
  }
  add(num) {
    console.log("add", num);
    this.value += num;
    return this;
  }
  subtract(num) {
    console.log("subtract", num);
    this.value -= num;
    return this;
  }
  multiply(num) {
    console.log("multiply", num);
    this.value *= num;
    return this;
  }
  divide(num) {
    console.log("divide", num);
    this.value /= num;
    return this;
  }
}

const num = new ASMD(0);
const result = num.add(10).subtract(2).divide(4).multiply(100).value;
console.log(result);