实现一个JSON.stringify
JSON . stringify ( value[ , replacer [ , space] ] ) :
Boolean | Number| String
类型会自动转换成对应的原始值。
undefined
、任意函数以及symbol
,会被忽略(出现在非数组对象的属性值中时),或者被转换成 null
(出现在数组中时)。
不可枚举的属性会被忽略如果一个对象的属性值通过某种间接的方式指回该对象本身,即循环引用,属性也会被忽略
如果一个对象的属性值通过某种间接的方式指回该对象本身,即循环引用,属性也会被忽略
function jsonStringify ( obj ) {
let type = typeof obj;
if ( type !== "object" ) {
if ( / string|undefined|function / . test ( type) ) {
obj = '"' + obj + '"' ;
}
return String ( obj) ;
} else {
let json = [ ]
let arr = Array. isArray ( obj)
for ( let k in obj) {
let v = obj[ k] ;
let type = typeof v;
if ( / string|undefined|function / . test ( type) ) {
v = '"' + v + '"' ;
} else if ( type === "object" ) {
v = jsonStringify ( v) ;
}
json. push ( ( arr ? "" : '"' + k + '":' ) + String ( v) ) ;
}
return ( arr ? "[" : "{" ) + String ( json) + ( arr ? "]" : "}" )
}
}
jsonStringify ( {
x : 5 } )
jsonStringify ( [ 1 , "false" , false ] )
jsonStringify ( {
b : undefined } )
手写 Promise
const PENDING = "pending" ;
const RESOLVED = "resolved" ;
const REJECTED = "rejected" ;
function MyPromise ( fn ) {
var self = this ;
this . state = PENDING ;
this . value = null ;
this . resolvedCallbacks = [ ] ;
this . rejectedCallbacks = [ ] ;
function resolve ( value ) {
if ( value instanceof MyPromise ) {
return value. then ( resolve, reject) ;
}
setTimeout ( ( ) => {
if ( self. state === PENDING ) {
self. state = RESOLVED ;
self. value = value;
self. resolvedCallbacks. forEach ( callback => {
callback ( value) ;
} ) ;
}
} , 0 ) ;
}
function reject ( value ) {
setTimeout ( ( ) => {
if ( self. state === PENDING ) {
self. state = REJECTED ;
self. value = value;
self. rejectedCallbacks. forEach ( callback => {
callback ( value) ;
} ) ;
}
} , 0 ) ;
}
try {
fn ( resolve, reject) ;
} catch ( e) {
reject ( e) ;
}
}
MyPromise . prototype. then = function ( onResolved, onRejected ) {
onResolved =
typeof onResolved === "function"
? onResolved
: function ( value ) {
return value;
} ;
onRejected =
typeof onRejected === "function"
? onRejected
: function ( error ) {
throw error;
} ;
if ( this . state === PENDING ) {
this . resolvedCallbacks. push ( onResolved) ;
this . rejectedCallbacks. push ( onRejected) ;
}
if ( this . state === RESOLVED ) {
onResolved ( this . value) ;
}
if ( this . state === REJECTED ) {
onRejected ( this . value) ;
}
} ;
实现Promise
var PromisePolyfill = ( function ( ) {
function tryToResolve ( value) {
if ( this === value) {
throw TypeError ( 'Chaining cycle detected for promise! ')
}
if ( value !== null &&
( typeof value === 'object ' || typeof value === 'function') ) {
try {
var then = value. then
var thenAlreadyCalledOrThrow = false
if ( typeof then === 'function') {
then. bind ( value) (
function ( value2) {
if ( thenAlreadyCalledOrThrow) return
thenAlreadyCalledOrThrow = true
tryToResolve. bind ( this , value2) ( )
} . bind ( this ) ,
function ( reason2) {
if ( thenAlreadyCalledOrThrow) return
thenAlreadyCalledOrThrow = true
resolveOrReject. bind ( this , 'rejected', reason2) ( )
} . bind ( this )
)
} else {
resolveOrReject. bind ( this , 'resolved', value) ( )
}
} catch ( e) {
if ( thenAlreadyCalledOrThrow) return
thenAlreadyCalledOrThrow = true
resolveOrReject. bind ( this , 'rejected', e) ( )
}
} else {
resolveOrReject. bind ( this , 'resolved', value) ( )
}
}
function resolveOrReject ( status, data ) {
if ( this . status !== 'pending') return
this . status = status
this . data = data
if ( status === 'resolved') {
for ( var i = 0 ; i < this . resolveList. length; ++ i) {
this . resolveList[ i] ( )
}
} else {
for ( i = 0 ; i < this . rejectList. length; ++ i) {
this . rejectList[ i] ( )
}
}
}
function Promise ( executor) {
if