[JS基础回顾] 链式调用的实现

1,202 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

目录

  1. 构造函数 + 返回this 实现
  2. 普通对象 + 返回this 实现
  3. class实现(同一)

一 构造函数+返回this 实现

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

1) (箭头函数)错误写法

箭头函数导致构造函数原型上的this指向window, 之所以加上错误写法,是要注意 调用方式

function Fn1(name){
    this.name = name;
}
Fn1.prototype.test = (param) => {
    // 此函数中this指向window,故在构造函数中不建议使用箭头函数
    console.log(this,param);
    return this; 
}
var instance = new Fn1('andy');

instance.test('1次调用').test('2次').test('3次')

image.png

2) 构造函数+原型方法(返回this) 正确写法

2.1) new的实现

通过 new 来调用构造函数, 从以往 new 的实现中可以 发现其中 关键点

function _new(constructor, ...args) {
    // 构造函数类型合法判断
    if(typeof constructor !== 'function') {
      throw new Error('constructor must be a function');
    }
    // 新建空对象实例
    let obj = new Object();
    // 将构造函数的原型绑定到新创的对象实例上
    obj.__proto__ = Object.create(constructor.prototype); 
    // 调用构造函数并判断返回值
    let res = constructor.apply(obj,  args); // `关注此行即可`
    let isObject = typeof res === 'object' && res !== null;
    let isFunction = typeof res === 'function';
    // 如果有返回值且返回值是对象类型,那么就将它作为返回值,否则就返回之前新建的对象
    return isObject || isFunction ? res : obj;
};

2.2) 构造函数+原型方法(返回this) 正确写法
function Fn1(name){
    this.name = name;
}
Fn1.prototype.test = function(param) {
    console.log(this,param);
    return this;
}
// new 调用后, 实例 instance 是new时创建的空对象,`并将this指向了创建的实例对象 instance`
var instance = new Fn1('andy');

instance.test('1次调用').test('2次').test('3次')
// '1次调用'  '2次'   '3次'

image.png

二 普通对象 + 返回this 实现

利用 普通对象中的this 通过 obj.a的方式调用时, this指向此普通对象来实现

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

三 class实现(同一)

1) 错误写法

调用时错误,可以用括号括起来,或者先把实例保存到变量在调用.

class Obj1 {
    a(){
        console.log('a');
        return this;
    }
    b(){
        console.log('b');
        return this;
    }
}

new Obj1.a().a().b().b().a();// 调用时错误,可以用括号括起来,或者先把实例保存到变量在调用.

image.png

1) 正确写法

class Obj1 {
    a(){
        console.log('a');
        return this;
    }
    b(){
        console.log('b');
        return this;
    }
}

(new Obj1).a().a().b().b().a();
// a a b b a

总结

  • 链式调用最早应该是在JQ中实现, 我们也在那个时代屡试不爽. 其实现关键一点就是 return this, 另外要 注意调用方式 即可