前言
之前有过一次面试,面试官问 promise 相干的知识点,而后我答复了,他诘问说 promise 的链式怎么实现?我过后没反馈过去。面试官很有急躁,说 jquery 也是有链式的,你看过 jquery 的源码吗?它的链式怎么写的?我还是不晓得,起初没通过面试,这个知识点常被我回顾,当初正好有工夫,来写一写
注释
答案是:返回this
先来一个例子:
var person = { name: 'johan', age: 28, sayName: function() { console.log('my name is' + this.name) }, sayAge: function() { console.log('my age is ' + this.age) }}
命名一个对象,它有两个办法,sayName 和 sayAge ,如果我想这样示意 person.sayName().sayAge()
呢?怎么做,在办法 sayName 和 sayAge 中返回 this,即
var person = { name: 'johan', age: 28, sayName: function() { console.log('my name is' + this.name) return this; }, sayAge: function() { console.log('my age is ' + this.age) return this; }}
这就是示意,调用办法 sayName 、sayAge 后,返回调用者,即例子 person.sayName()
,person 调用 sayName,调用完后返回值还是 person。所以它能够持续链式调用 sayAge,因为它示意的还是 person
Promise 中的链式
Promise 自身没有链式,然而 Promise 的实例对象中的 then 有链式
function MyPromise(executor) { }MyPromise.prototype.then = function (onFulfilled, onRejected) { return new Promise((resolve, reject) => { ... })}
当你应用 Promise 时,个别是这样应用:
let promise = new Promise((resolve, reject) => { setTimeout(resolve, 1000)})promise.then(() => { console.log('1s后显示')})
如果加上链式
promise.then(() => { console.log('1s后显示,第一个')}).then(() => { console.log('1s后显示,第二个')})
所以很显著,每调用一次 then,就是返回一个实例对象(return new Promise
)
Jquery 中的链式
源码太多内容,就拿 core.js
中的代码为例子
jQuery.fn = jQuery.prototype = { // The current version of jQuery being used jquery: version, constructor: jQuery, // The default length of a jQuery object is 0 length: 0, toArray: function() { return slice.call( this ); }, // Get the Nth element in the matched element set OR // Get the whole matched element set as a clean array get: function( num ) { // Return all the elements in a clean array if ( num == null ) { return slice.call( this ); } // Return just the one element from the set return num < 0 ? this[ num + this.length ] : this[ num ]; }, // Take an array of elements and push it onto the stack // (returning the new matched element set) pushStack: function( elems ) { // Build a new jQuery matched element set var ret = jQuery.merge( this.constructor(), elems ); // Add the old object onto the stack (as a reference) ret.prevObject = this; // Return the newly-formed element set return ret; }, // Execute a callback for every element in the matched set. each: function( callback ) { return jQuery.each( this, callback ); }, map: function( callback ) { return this.pushStack( jQuery.map( this, function( elem, i ) { return callback.call( elem, i, elem ); } ) ); }, slice: function() { return this.pushStack( slice.apply( this, arguments ) ); }, first: function() { return this.eq( 0 ); }, last: function() { return this.eq( -1 ); }, even: function() { return this.pushStack( jQuery.grep( this, function( _elem, i ) { return ( i + 1 ) % 2; } ) ); }, odd: function() { return this.pushStack( jQuery.grep( this, function( _elem, i ) { return i % 2; } ) ); }, eq: function( i ) { var len = this.length, j = +i + ( i < 0 ? len : 0 ); return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); }, end: function() { return this.prevObject || this.constructor(); }};
咱们不必看全副,但看其中的办法,是不是和最开始的例子很像——return this
所以链式不可怕,可怕的是,动都不动就自我劝退
本文参加了 SegmentFault 思否征文「如何“反杀”面试官?」,欢送正在浏览的你也退出。