Object.create
function create ( obj) {
function F ( ) { }
F . prototype = obj
return new F ( )
}
instanceof 方法
首先获取类型的原型 然后获得对象的原型 然后一直循环判断对象的原型是否等于类型的原型,直到对象原型为 null,因为原型链最终为 null
function myInstanceof ( left, right) {
let proto = Object. getPrototypeOf ( left) ,
prototype = right. prototype;
while ( true ) {
if ( ! proto) return false ;
if ( proto === prototype) return true ;
proto = Object. getPrototypeOf ( proto) ;
}
}
new 操作符
首先创建了一个新的空对象 设置原型,将对象的原型设置为函数的 prototype 对象。 让函数的 this 指向这个对象,执行构造函数的代码(为这个新对象添加属性) 判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象。
function objectFactory ( ) {
let newObject = null ;
let constructor = Array. prototype. shift. call ( arguments) ;
let result = null ;
if ( typeof constructor !== "function" ) {
console. error ( "type error" ) ;
return ;
}
newObject = Object. create ( constructor. prototype) ;
result = constructor. apply ( newObject, arguments) ;
let flag = result && ( typeof result === "object" || typeof result === "function" ) ;
return flag ? result : newObject;
}
objectFactory ( 构造函数, 初始化参数) ;
promise
const PENDING = 'pending' ;
const FULFILLED = 'fulfilled' ;
const REJECTED = 'rejected' ;
function runMicroTask ( callback) {
if ( globalThis. process && globalThis. process. nextTick) {
process. nextTick ( callback) ;
} else if ( globalThis. MutationObserver) {
const p = document. createElement ( 'p' ) ;
const observer = new MutationObserver ( callback) ;
observer. observe ( p, {
childList: true ,
} ) ;
p. innerHTML = '1' ;
} else {
setTimeout ( callback, 0 ) ;
}
}
function isPromise ( obj) {
return ! ! ( obj && typeof obj === 'object' && typeof obj. then === 'function' ) ;
}
class MyPromise {
constructor ( executor) {
this . _state = PENDING ;
this . _value = undefined;
this . _handlers = [ ] ;
try {
executor ( this . _resolve. bind ( this ) , this . _reject. bind ( this ) ) ;
} catch ( error ) {
this . _reject ( error) ;
console. error ( error) ;
}
}
_pushHandler ( executor, state, resolve, reject) {
this . _handlers. push ( {
executor,
state,
resolve,
reject,
} ) ;
}
_runHandlers ( ) {
if ( this . _state === PENDING ) {
return ;
}
while ( this . _handlers[ 0 ] ) {
const handler = this . _handlers[ 0 ] ;
this . _runOneHandler ( handler) ;
this . _handlers. shift ( ) ;
}
}
_runOneHandler ( { executor, state, resolve, reject } ) {
runMicroTask ( ( ) => {
if ( this . _state !== state) {
return ;
}
if ( typeof executor !== 'function' ) {
this . _state === FULFILLED ? resolve ( this . _value) : reject ( this . _value) ;
return ;
}
try {
const result = executor ( this . _value) ;
if ( isPromise ( result) ) {
result. then ( resolve, reject) ;
} else {
resolve ( result) ;
}
} catch ( error ) {
reject ( error) ;
console. error ( error) ;
}
} ) ;
}
then ( onFulfilled, onRejected) {
return new MyPromise ( ( resolve, reject) => {
this . _pushHandler ( onFulfilled, FULFILLED , resolve, reject) ;
this . _pushHandler ( onRejected, REJECTED , resolve, reject) ;
this . _runHandlers ( ) ;
} ) ;
}
catch ( onRejected) {
return this . then ( null , onRejected) ;
}
finally ( onSettled) {
return this . then (
( data) => {
onSettled ( ) ;
return data;
} ,
( reason) => {
onSettled ( ) ;
throw reason;
}
) ;
}
_changeState ( newState, value) {
if ( this . _state !== PENDING ) {
return ;
}
this . _state = newState;
this . _value = value;
this . _runHandlers ( ) ;
}
_resolve ( data) {
this . _changeState ( FULFILLED , data) ;
}
_reject ( reason) {
this . _changeState ( REJECTED , reason) ;
}
static resolve ( data) {
if ( data instanceof MyPromise ) {
return data;
}
return new MyPromise ( ( resolve, reject) => {
if ( isPromise ( data) ) {
data. then ( resolve, reject) ;
} else {
resolve ( data) ;
}
} ) ;
}
static reject ( reason) {
return new MyPromise ( ( resolve, reject) => {
reject ( reason) ;
} ) ;
}
static all ( proms) {
return new MyPromise ( ( resolve, reject) => {
try {
const results = [ ] ;
let count = 0 ;
let fulfilledCount = 0 ;
for ( const p of proms) {
let i = count;
count++ ;
MyPromise. resolve ( p) . then ( ( data) => {
fulfilledCount++ ;
results[ i] = data;
if ( fulfilledCount === count) {
resolve ( results) ;
}
} , reject) ;
}
if ( count === 0 ) {
resolve ( results) ;
}
} catch ( error ) {
reject ( error) ;
console. error ( error) ;
}
} ) ;
}
static allSettled ( proms) {
const ps = [ ] ;
for ( const p of proms) {
ps. push (
MyPromise. resolve ( p) . then (
( value) => ( {
status: FULFILLED ,
value,
} ) ,
( reason) => ( {
status: REJECTED ,
reason,
} )
)
) ;
}
return MyPromise. all ( ps) ;
}
static race ( proms) {
return new MyPromise ( ( resolve, reject) => {
for ( const p of proms) {
MyPromise. resolve ( p) . then ( resolve, reject) ;
}
} ) ;
}
}
类型判断函数
function getType ( value) {
if ( value === null ) {
return value + "" ;
}
if ( typeof value === "object" ) {
let valueClass = Object. prototype. toString. call ( value) ,
type = valueClass. split ( " " ) [ 1 ] . split ( "" ) ;
type. pop ( ) ;
return type. join ( "" ) . toLowerCase ( ) ;
} else {
return typeof value;
}
}
call 函数
判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可能出现使用 call 等方式调用的情况。 判断传入上下文对象是否存在,如果不存在,则设置为 window 。 处理传入的参数,截取第一个参数后的所有参数。 将函数作为上下文对象的一个属性。 使用上下文对象来调用这个方法,并保存返回结果。 删除刚才新增的属性。 返回结果。
Function. prototype. myCall = function ( context) {
if ( typeof this !== "function" ) {
console. error ( "type error" ) ;
}
let args = [ ... arguments] . slice ( 1 ) ,
result = null ;
context = context || window;
context. fn = this ;
result = context. fn ( ... args) ;
delete context. fn;
return result;
} ;
apply 函数
Function. prototype. myApply = function ( context) {
if ( typeof this !== "function" ) {
throw new TypeError ( "Error" ) ;
}
let result = null ;
context = context || window;
context. fn = this ;
if ( arguments[ 1 ] ) {
result = context. fn ( ... arguments[ 1 ] ) ;
} else {
result = context. fn ( ) ;
}
delete context. fn;
return result;
} ;
bind 函数
判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可能出现使用 call 等方式调用的情况。 保存当前函数的引用,获取其余传入参数值。 创建一个函数返回 函数内部使用 apply 来绑定函数调用,需要判断函数作为构造函数的情况,这个时候需要传入当前函数的 this 给 apply 调用,其余情况都传入指定的上下文对象。
Function. prototype. myBind = function ( context) {
if ( typeof this !== "function" ) {
throw new TypeError ( "Error" ) ;
}
var args = [ ... arguments] . slice ( 1 ) ,
fn = this ;
return function Fn ( ) {
return fn. apply (
this instanceof Fn ? this : context,
args. concat ( ... arguments)
) ;
} ;
} ;
函数柯里化的实现
function curry ( fn, args) {
let length = fn. length;
args = args || [ ] ;
return function ( ) {
let subArgs = args. slice ( 0 ) ;
for ( let i = 0 ; i < arguments. length; i++ ) {
subArgs. push ( arguments[ i] ) ;
}
if ( subArgs. length >= length) {
return fn. apply ( this , subArgs) ;
} else {
return curry. call ( this , fn, subArgs) ;
}
} ;
}
function curry ( fn, ... args) {
return fn. length <= args. length ? fn ( ... args) : curry. bind ( null , fn, ... args) ;
}
实现AJAX请求
创建一个 XMLHttpRequest 对象。 在这个对象上使用 open 方法创建一个 HTTP 请求,open 方法所需要的参数是请求的方法、请求的地址、是否异步和用户的认证信息。 在发起请求前,可以为这个对象添加一些信息和监听函数。比如说可以通过 setRequestHeader 方法来为请求添加头信息。还可以为这个对象添加一个状态监听函数。一个 XMLHttpRequest 对象一共有 5 个状态,当它的状态变化时会触发onreadystatechange 事件,可以通过设置监听函数,来处理请求成功后的结果。当对象的 readyState 变为 4 的时候,代表服务器返回的数据接收完成,这个时候可以通过判断请求的状态,如果状态是 2xx 或者 304 的话则代表返回正常。这个时候就可以通过 response 中的数据来对页面进行更新了。 当对象的属性和监听函数设置完成后,最后调用 sent 方法来向服务器发起请求,可以传入参数作为发送的数据体。
const SERVER_URL = "/server" ;
let xhr = new XMLHttpRequest ( ) ;
xhr. open ( "GET" , SERVER_URL , true ) ;
xhr. onreadystatechange = function ( ) {
if ( this . readyState !== 4 ) return ;
if ( this . status === 200 ) {
handle ( this . response) ;
} else {
console. error ( this . statusText) ;
}
} ;
xhr. onerror = function ( ) {
console. error ( this . statusText) ;
} ;
xhr. responseType = "json" ;
xhr. setRequestHeader ( "Accept" , "application/json" ) ;
xhr. send ( null ) ;
Promise封装AJAX请求
function getJSON ( url) {
let promise = new Promise ( function ( resolve, reject) {
let xhr = new XMLHttpRequest ( ) ;
xhr. open ( "GET" , url, true ) ;
xhr. onreadystatechange = function ( ) {
if ( this . readyState !== 4 ) return ;
if ( this . status === 200 ) {
resolve ( this . response) ;
} else {
reject ( new Error ( this . statusText) ) ;
}
} ;
xhr. onerror = function ( ) {
reject ( new Error ( this . statusText) ) ;
} ;
xhr. responseType = "json" ;
xhr. setRequestHeader ( "Accept" , "application/json" ) ;
xhr. send ( null ) ;
} ) ;
return promise;
}
浅拷贝
function shallowCopy ( object) {
if ( ! object || typeof object !== "object" ) return ;
let newObject = Array. isArray ( object) ? [ ] : { } ;
for ( let key in object) {
if ( object. hasOwnProperty ( key) ) {
newObject[ key] = object[ key] ;
}
}
return newObject;
}
function shallowCopy ( object) {
if ( ! object || typeof object !== "object" ) return ;
let newObject = Array. isArray ( object) ? [ ] : { } ;
for ( let key in object) {
if ( object. hasOwnProperty ( key) ) {
newObject[ key] = object[ key] ;
}
}
return newObject;
}
function shallowCopy ( object) {
if ( ! object || typeof object !== "object" ) return ;
let newObject = Array. isArray ( object) ? [ ] : { } ;
for ( let key in object) {
if ( object. hasOwnProperty ( key) ) {
newObject[ key] = object[ key] ;
}
}
return newObject;
}
深拷贝
function deepCopy ( object) {
if ( ! object || typeof object !== "object" ) return ;
let newObject = Array. isArray ( object) ? [ ] : { } ;
for ( let key in object) {
if ( object. hasOwnProperty ( key) ) {
newObject[ key] =
typeof object[ key] === "object" ? deepCopy ( object[ key] ) : object[ key] ;
}
}
return newObject;
}
数组的扁平化
递归
let arr = [ 1 , [ 2 , [ 3 , 4 , 5 ] ] ] ;
function flatten ( arr) {
let result = [ ] ;
for ( let i = 0 ; i < arr. length; i++ ) {
if ( Array. isArray ( arr[ i] ) ) {
result = result. concat ( flatten ( arr[ i] ) ) ;
} else {
result. push ( arr[ i] ) ;
}
}
return result;
}
flatten ( arr) ;
reduce 函数
let arr = [ 1 , [ 2 , [ 3 , 4 ] ] ] ;
function flatten ( arr) {
return arr. reduce ( function ( prev, next) {
return prev. concat ( Array. isArray ( next) ? flatten ( next) : next)
} , [ ] )
}
console. log ( flatten ( arr) ) ;
扩展运算符
let arr = [ 1 , [ 2 , [ 3 , 4 ] ] ] ;
function flatten ( arr) {
while ( arr. some ( item => Array. isArray ( item) ) ) {
arr = [ ] . concat ( ... arr) ;
}
return arr;
}
console. log ( flatten ( arr) ) ;
split 和 toString
let arr = [ 1 , [ 2 , [ 3 , 4 ] ] ] ;
function flatten ( arr) {
return arr. toString ( ) . split ( ',' ) ;
}
console. log ( flatten ( arr) ) ;
ES6 中的 flat
let arr = [ 1 , [ 2 , [ 3 , 4 ] ] ] ;
function flatten ( arr) {
return arr. flat ( Infinity ) ;
}
console. log ( flatten ( arr) ) ;
数组的flat方法
function _flat ( arr, depth) {
if ( ! Array. isArray ( arr) || depth <= 0 ) {
return arr;
}
return arr. reduce ( ( prev, cur) => {
if ( Array. isArray ( cur) ) {
return prev. concat ( _flat ( cur, depth - 1 ) )
} else {
return prev. concat ( cur) ;
}
} , [ ] ) ;
}
数组的push方法
let arr = [ ] ;
Array. prototype. push = function ( ) {
for ( let i = 0 ; i < arguments. length ; i++ ) {
this [ this . length] = arguments[ i] ;
}
return this . length;
}
数组的filter方法
Array. prototype. _filter = function ( fn) {
if ( typeof fn !== "function" ) {
throw Error ( '参数必须是一个函数' ) ;
}
const res = [ ] ;
for ( let i = 0 , len = this . length; i < len; i++ ) {
fn ( this [ i] ) && res. push ( this [ i] ) ;
}
return res;
}
数组的map方法
Array. prototype. _map = function ( fn) {
if ( typeof fn !== "function" ) {
throw Error ( '参数必须是一个函数' ) ;
}
const res = [ ] ;
for ( let i = 0 , len = this . length; i < len; i++ ) {
res. push ( fn ( this [ i] ) ) ;
}
return res;
}
字符串的repeat方法
function repeat ( s, n) {
return ( new Array ( n + 1 ) ) . join ( s) ;
}
字符串翻转
String. prototype. _reverse = function ( a) {
return a. split ( "" ) . reverse ( ) . join ( "" ) ;
}
var obj = new String ( ) ;
var res = obj. _reverse ( 'hello' ) ;
console. log ( res) ;
解析URL Params 为对象
function parseParam ( url) {
const paramsStr = /.+\?(.+)$/ . exec ( url) [ 1 ] ;
const paramsArr = paramsStr. split ( '&' ) ;
let paramsObj = { } ;
paramsArr. forEach ( param => {
if ( /=/ . test ( param) ) {
let [ key, val] = param. split ( '=' ) ;
val = decodeURIComponent ( val) ;
val = /^\d+$/ . test ( val) ? parseFloat ( val) : val;
if ( paramsObj. hasOwnProperty ( key) ) {
paramsObj[ key] = [ ] . concat ( paramsObj[ key] , val) ;
} else {
paramsObj[ key] = val;
}
} else {
paramsObj[ param] = true ;
}
} )
return paramsObj;
}
`` `# 手写代码
## Object.create
` `` js
function create ( obj) {
function F ( ) { }
F . prototype = obj
return new F ( )
}
instanceof 方法
首先获取类型的原型 然后获得对象的原型 然后一直循环判断对象的原型是否等于类型的原型,直到对象原型为 null,因为原型链最终为 null
function myInstanceof ( left, right) {
let proto = Object. getPrototypeOf ( left) ,
prototype = right. prototype;
while ( true ) {
if ( ! proto) return false ;
if ( proto === prototype) return true ;
proto = Object. getPrototypeOf ( proto) ;
}
}
new 操作符
首先创建了一个新的空对象 设置原型,将对象的原型设置为函数的 prototype 对象。 让函数的 this 指向这个对象,执行构造函数的代码(为这个新对象添加属性) 判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象。
function objectFactory ( ) {
let newObject = null ;
let constructor = Array. prototype. shift. call ( arguments) ;
let result = null ;
if ( typeof constructor !== "function" ) {
console. error ( "type error" ) ;
return ;
}
newObject = Object. create ( constructor. prototype) ;
result = constructor. apply ( newObject, arguments) ;
let flag = result && ( typeof result === "object" || typeof result === "function" ) ;
return flag ? result : newObject;
}
objectFactory ( 构造函数, 初始化参数) ;
promise
const PENDING = 'pending' ;
const FULFILLED = 'fulfilled' ;
const REJECTED = 'rejected' ;
function runMicroTask ( callback) {
if ( globalThis. process && globalThis. process. nextTick) {
process. nextTick ( callback) ;
} else if ( globalThis. MutationObserver) {
const p = document. createElement ( 'p' ) ;
const observer = new MutationObserver ( callback) ;
observer. observe ( p, {
childList: true ,
} ) ;
p. innerHTML = '1' ;
} else {
setTimeout ( callback, 0 ) ;
}
}
function isPromise ( obj) {
return ! ! ( obj && typeof obj === 'object' && typeof obj. then === 'function' ) ;
}
class MyPromise {
constructor ( executor) {
this . _state = PENDING ;
this . _value = undefined;
this . _handlers = [ ] ;
try {
executor ( this . _resolve. bind ( this ) , this . _reject. bind ( this ) ) ;
} catch ( error ) {
this . _reject ( error) ;
console. error ( error) ;
}
}
_pushHandler ( executor, state, resolve, reject) {
this . _handlers. push ( {
executor,
state,
resolve,
reject,
} ) ;
}
_runHandlers ( ) {
if ( this . _state === PENDING ) {
return ;
}
while ( this . _handlers[ 0 ] ) {
const handler = this . _handlers[ 0 ] ;
this . _runOneHandler ( handler) ;
this . _handlers. shift ( ) ;
}
}
_runOneHandler ( { executor, state, resolve, reject } ) {
runMicroTask ( ( ) => {
if ( this . _state !== state) {
return ;
}
if ( typeof executor !== 'function' ) {
this . _state === FULFILLED ? resolve ( this . _value) : reject ( this . _value) ;
return ;
}
try {
const result = executor ( this . _value) ;
if ( isPromise ( result) ) {
result. then ( resolve, reject) ;
} else {
resolve ( result) ;
}
} catch ( error ) {
reject ( error) ;
console. error ( error) ;
}
} ) ;
}
then ( onFulfilled, onRejected) {
return new MyPromise ( ( resolve, reject) => {
this . _pushHandler ( onFulfilled, FULFILLED , resolve, reject) ;
this . _pushHandler ( onRejected, REJECTED , resolve, reject) ;
this . _runHandlers ( ) ;
} ) ;
}
catch ( onRejected) {
return this . then ( null , onRejected) ;
}
finally ( onSettled) {
return this . then (
( data) => {
onSettled ( ) ;
return data;
} ,
( reason) => {
onSettled ( ) ;
throw reason;
}
) ;
}
_changeState ( newState, value) {
if ( this . _state !== PENDING ) {
return ;
}
this . _state = newState;
this . _value = value;
this . _runHandlers ( ) ;
}
_resolve ( data) {
this . _changeState ( FULFILLED , data) ;
}
_reject ( reason) {
this . _changeState ( REJECTED , reason) ;
}
static resolve ( data) {
if ( data instanceof MyPromise ) {
return data;
}
return new MyPromise ( ( resolve, reject) => {
if ( isPromise ( data) ) {
data. then ( resolve, reject) ;
} else {
resolve ( data) ;
}
} ) ;
}
static reject ( reason) {
return new MyPromise ( ( resolve, reject) => {
reject ( reason) ;
} ) ;
}
static all ( proms) {
return new MyPromise ( ( resolve, reject) => {
try {
const results = [ ] ;
let count = 0 ;
let fulfilledCount = 0 ;
for ( const p of proms) {
let i = count;
count++ ;
MyPromise. resolve ( p) . then ( ( data) => {
fulfilledCount++ ;
results[ i] = data;
if ( fulfilledCount === count) {
resolve ( results) ;
}
} , reject) ;
}
if ( count === 0 ) {
resolve ( results) ;
}
} catch ( error ) {
reject ( error) ;
console. error ( error) ;
}
} ) ;
}
static allSettled ( proms) {
const ps = [ ] ;
for ( const p of proms) {
ps. push (
MyPromise. resolve ( p) . then (
( value) => ( {
status: FULFILLED ,
value,
} ) ,
( reason) => ( {
status: REJECTED ,
reason,
} )
)
) ;
}
return MyPromise. all ( ps) ;
}
static race ( proms) {
return new MyPromise ( ( resolve, reject) => {
for ( const p of proms) {
MyPromise. resolve ( p) . then ( resolve, reject) ;
}
} ) ;
}
}
类型判断函数
function getType ( value) {
if ( value === null ) {
return value + "" ;
}
if ( typeof value === "object" ) {
let valueClass = Object. prototype. toString. call ( value) ,
type = valueClass. split ( " " ) [ 1 ] . split ( "" ) ;
type. pop ( ) ;
return type. join ( "" ) . toLowerCase ( ) ;
} else {
return typeof value;
}
}
call 函数
判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可能出现使用 call 等方式调用的情况。 判断传入上下文对象是否存在,如果不存在,则设置为 window 。 处理传入的参数,截取第一个参数后的所有参数。 将函数作为上下文对象的一个属性。 使用上下文对象来调用这个方法,并保存返回结果。 删除刚才新增的属性。 返回结果。
Function. prototype. myCall = function ( context) {
if ( typeof this !== "function" ) {
console. error ( "type error" ) ;
}
let args = [ ... arguments] . slice ( 1 ) ,
result = null ;
context = context || window;
context. fn = this ;
result = context. fn ( ... args) ;
delete context. fn;
return result;
} ;
apply 函数
Function. prototype. myApply = function ( context) {
if ( typeof this !== "function" ) {
throw new TypeError ( "Error" ) ;
}
let result = null ;
context = context || window;
context. fn = this ;
if ( arguments[ 1 ] ) {
result = context. fn ( ... arguments[ 1 ] ) ;
} else {
result = context. fn ( ) ;
}
delete context. fn;
return result;
} ;
bind 函数
判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可能出现使用 call 等方式调用的情况。 保存当前函数的引用,获取其余传入参数值。 创建一个函数返回 函数内部使用 apply 来绑定函数调用,需要判断函数作为构造函数的情况,这个时候需要传入当前函数的 this 给 apply 调用,其余情况都传入指定的上下文对象。
Function. prototype. myBind = function ( context) {
if ( typeof this !== "function" ) {
throw new TypeError ( "Error" ) ;
}
var args = [ ... arguments] . slice ( 1 ) ,
fn = this ;
return function Fn ( ) {
return fn. apply (
this instanceof Fn ? this : context,
args. concat ( ... arguments)
) ;
} ;
} ;
函数柯里化的实现
function curry ( fn, args) {
let length = fn. length;
args = args || [ ] ;
return function ( ) {
let subArgs = args. slice ( 0 ) ;
for ( let i = 0 ; i < arguments. length; i++ ) {
subArgs. push ( arguments[ i] ) ;
}
if ( subArgs. length >= length) {
return fn. apply ( this , subArgs) ;
} else {
return curry. call ( this , fn, subArgs) ;
}
} ;
}
function curry ( fn, ... args) {
return fn. length <= args. length ? fn ( ... args) : curry. bind ( null , fn, ... args) ;
}
实现AJAX请求
创建一个 XMLHttpRequest 对象。 在这个对象上使用 open 方法创建一个 HTTP 请求,open 方法所需要的参数是请求的方法、请求的地址、是否异步和用户的认证信息。 在发起请求前,可以为这个对象添加一些信息和监听函数。比如说可以通过 setRequestHeader 方法来为请求添加头信息。还可以为这个对象添加一个状态监听函数。一个 XMLHttpRequest 对象一共有 5 个状态,当它的状态变化时会触发onreadystatechange 事件,可以通过设置监听函数,来处理请求成功后的结果。当对象的 readyState 变为 4 的时候,代表服务器返回的数据接收完成,这个时候可以通过判断请求的状态,如果状态是 2xx 或者 304 的话则代表返回正常。这个时候就可以通过 response 中的数据来对页面进行更新了。 当对象的属性和监听函数设置完成后,最后调用 sent 方法来向服务器发起请求,可以传入参数作为发送的数据体。
const SERVER_URL = "/server" ;
let xhr = new XMLHttpRequest ( ) ;
xhr. open ( "GET" , SERVER_URL , true ) ;
xhr. onreadystatechange = function ( ) {
if ( this . readyState !== 4 ) return ;
if ( this . status === 200 ) {
handle ( this . response) ;
} else {
console. error ( this . statusText) ;
}
} ;
xhr. onerror = function ( ) {
console. error ( this . statusText) ;
} ;
xhr. responseType = "json" ;
xhr. setRequestHeader ( "Accept" , "application/json" ) ;
xhr. send ( null ) ;
Promise封装AJAX请求
function getJSON ( url) {
let promise = new Promise ( function ( resolve, reject) {
let xhr = new XMLHttpRequest ( ) ;
xhr. open ( "GET" , url, true ) ;
xhr. onreadystatechange = function ( ) {
if ( this . readyState !== 4 ) return ;
if ( this . status === 200 ) {
resolve ( this . response) ;
} else {
reject ( new Error ( this . statusText) ) ;
}
} ;
xhr. onerror = function ( ) {
reject ( new Error ( this . statusText) ) ;
} ;
xhr. responseType = "json" ;
xhr. setRequestHeader ( "Accept" , "application/json" ) ;
xhr. send ( null ) ;
} ) ;
return promise;
}
浅拷贝
function shallowCopy ( object) {
if ( ! object || typeof object !== "object" ) return ;
let newObject = Array. isArray ( object) ? [ ] : { } ;
for ( let key in object) {
if ( object. hasOwnProperty ( key) ) {
newObject[ key] = object[ key] ;
}
}
return newObject;
}
function shallowCopy ( object) {
if ( ! object || typeof object !== "object" ) return ;
let newObject = Array. isArray ( object) ? [ ] : { } ;
for ( let key in object) {
if ( object. hasOwnProperty ( key) ) {
newObject[ key] = object[ key] ;
}
}
return newObject;
}
function shallowCopy ( object) {
if ( ! object || typeof object !== "object" ) return ;
let newObject = Array. isArray ( object) ? [ ] : { } ;
for ( let key in object) {
if ( object. hasOwnProperty ( key) ) {
newObject[ key] = object[ key] ;
}
}
return newObject;
}
深拷贝
function deepCopy ( object) {
if ( ! object || typeof object !== "object" ) return ;
let newObject = Array. isArray ( object) ? [ ] : { } ;
for ( let key in object) {
if ( object. hasOwnProperty ( key) ) {
newObject[ key] =
typeof object[ key] === "object" ? deepCopy ( object[ key] ) : object[ key] ;
}
}
return newObject;
}
数组的扁平化
递归
let arr = [ 1 , [ 2 , [ 3 , 4 , 5 ] ] ] ;
function flatten ( arr) {
let result = [ ] ;
for ( let i = 0 ; i < arr. length; i++ ) {
if ( Array. isArray ( arr[ i] ) ) {
result = result. concat ( flatten ( arr[ i] ) ) ;
} else {
result. push ( arr[ i] ) ;
}
}
return result;
}
flatten ( arr) ;
reduce 函数
let arr = [ 1 , [ 2 , [ 3 , 4 ] ] ] ;
function flatten ( arr) {
return arr. reduce ( function ( prev, next) {
return prev. concat ( Array. isArray ( next) ? flatten ( next) : next)
} , [ ] )
}
console. log ( flatten ( arr) ) ;
扩展运算符
let arr = [ 1 , [ 2 , [ 3 , 4 ] ] ] ;
function flatten ( arr) {
while ( arr. some ( item => Array. isArray ( item) ) ) {
arr = [ ] . concat ( ... arr) ;
}
return arr;
}
console. log ( flatten ( arr) ) ;
split 和 toString
let arr = [ 1 , [ 2 , [ 3 , 4 ] ] ] ;
function flatten ( arr) {
return arr. toString ( ) . split ( ',' ) ;
}
console. log ( flatten ( arr) ) ;
ES6 中的 flat
let arr = [ 1 , [ 2 , [ 3 , 4 ] ] ] ;
function flatten ( arr) {
return arr. flat ( Infinity ) ;
}
console. log ( flatten ( arr) ) ;
数组的flat方法
function _flat ( arr, depth) {
if ( ! Array. isArray ( arr) || depth <= 0 ) {
return arr;
}
return arr. reduce ( ( prev, cur) => {
if ( Array. isArray ( cur) ) {
return prev. concat ( _flat ( cur, depth - 1 ) )
} else {
return prev. concat ( cur) ;
}
} , [ ] ) ;
}
数组的push方法
let arr = [ ] ;
Array. prototype. push = function ( ) {
for ( let i = 0 ; i < arguments. length ; i++ ) {
this [ this . length] = arguments[ i] ;
}
return this . length;
}
数组的filter方法
Array. prototype. _filter = function ( fn) {
if ( typeof fn !== "function" ) {
throw Error ( '参数必须是一个函数' ) ;
}
const res = [ ] ;
for ( let i = 0 , len = this . length; i < len; i++ ) {
fn ( this [ i] ) && res. push ( this [ i] ) ;
}
return res;
}
数组的map方法
Array. prototype. _map = function ( fn) {
if ( typeof fn !== "function" ) {
throw Error ( '参数必须是一个函数' ) ;
}
const res = [ ] ;
for ( let i = 0 , len = this . length; i < len; i++ ) {
res. push ( fn ( this [ i] ) ) ;
}
return res;
}
字符串的repeat方法
function repeat ( s, n) {
return ( new Array ( n + 1 ) ) . join ( s) ;
}
字符串翻转
String. prototype. _reverse = function ( a) {
return a. split ( "" ) . reverse ( ) . join ( "" ) ;
}
var obj = new String ( ) ;
var res = obj. _reverse ( 'hello' ) ;
console. log ( res) ;
解析URL Params 为对象
function parseParam ( url) {
const paramsStr = /.+\?(.+)$/ . exec ( url) [ 1 ] ;
const paramsArr = paramsStr. split ( '&' ) ;
let paramsObj = { } ;
paramsArr. forEach ( param => {
if ( /=/ . test ( param) ) {
let [ key, val] = param. split ( '=' ) ;
val = decodeURIComponent ( val) ;
val = /^\d+$/ . test ( val) ? parseFloat ( val) : val;
if ( paramsObj. hasOwnProperty ( key) ) {
paramsObj[ key] = [ ] . concat ( paramsObj[ key] , val) ;
} else {
paramsObj[ key] = val;
}
} else {
paramsObj[ param] = true ;
}
} )
return paramsObj;
}