小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
目录
- 构造函数 + 返回this 实现
- 普通对象 + 返回this 实现
- 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次')
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次'
二 普通对象 + 返回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();// 调用时错误,可以用括号括起来,或者先把实例保存到变量在调用.
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
, 另外要注意调用方式
即可