call
Function. prototype. myCall = function ( context, ... args) {
context = context || window
let fn = Symbol ( 'fn' )
context[ fn] = this
let result = context[ fn] ( ... args)
delete context[ fn]
return result
}
apply
Function. prototype. myApply = function ( context, ... arg) {
context = context || window
let fn = Symbol ( 'fn' )
context[ fn] = this
let result = context[ fn] ( arg)
delete context[ fn]
return result
}
bind
Function. prototype. myBind = function ( _this, ... arg) {
if ( typeof this !== 'function' ) {
return throw new Error ( 'must be function' )
}
let fn = this ;
let fnNop = function ( ) { } ;
let resultFn = function ( ) {
fn. apply ( this instanceof fnNop ? this : _this,
arg. concat ( Array. prototype. slice. call ( arguments) ) )
}
fnNop. prototype = this . prototype;
resultFn. prototype = new fnNop ( ) ;
return resultFn
}
模拟new操作
function MyNew ( fn, ... arg) {
if ( typeof fn !== 'function' ) {
throw new TypeError ( 'Type Error' )
}
let child = Object. create ( fn. prototype)
let result = fn. apply ( child, arg)
return result instanceof Object ? result : child
}
instanceof
const myInstanceof = ( left, right) => {
if ( typeof left !== 'object' || left === null ) return false
left = Object. getPrototypeOf ( left) ;
right = right. prototype
while ( true ) {
if ( left === null ) return false ;
if ( left === right) return true ;
left = Object. getPrototypeOf ( left) ;
}
}
继承
function Parent ( ) {
this . name = 'parent' ;
}
function Child ( ) {
Parent. call ( this ) ;
this . type = 'children' ;
}
Child. prototype = Object. create ( Parent. prototype) ;
Child. prototype. constructor = Child;
图片懒加载
function lazyload ( ) {
const imgs = document. getElementsByTagName ( 'img' ) ;
const len = imgs. length;
const viewHeight = document. documentElement. clientHeight;
const scrollHeight = document. documentElement. scrollTop || document. body. scrollTop;
for ( let i = 0 ; i < len; i++ ) {
const offsetHeight = imgs[ i] . offsetTop;
if ( offsetHeight < viewHeight + scrollHeight) {
const src = imgs[ i] . dataset. src;
imgs[ i] . src = src;
}
}
}
渲染几万条数据不卡住页面
setTimeout ( ( ) => {
const total = 100000 ;
const once = 20 ;
const loopCount = Math. ceil ( total / once) ;
let countOfRender = 0 ;
const ul = document. querySelector ( 'ul' ) ;
function add ( ) {
const fragment = document. createDocumentFragment ( ) ;
for ( let i = 0 ; i < once; i++ ) {
const li = document. createElement ( 'li' ) ;
li. innerText = Math. floor ( Math. random ( ) * total) ;
fragment. appendChild ( li) ;
}
ul. appendChild ( fragment) ;
countOfRender += 1 ;
loop ( ) ;
}
function loop ( ) {
if ( countOfRender < loopCount) {
window. requestAnimationFrame ( add) ;
}
}
loop ( ) ;
} , 0 )
发布订阅者
class EventHub {
constructor ( ) {
this . bus = { }
}
add ( name, fn) {
this . bus[ name] ? this . bus[ name] . push ( fn) : this . bus[ name] = [ fn]
}
remove ( name, fn) {
if ( fn) {
this . bus[ name] = this . bus[ name] . filter ( item=> item=== fn)
} else {
delete this . bus[ name]
}
}
notice ( name, msg) {
this . bus[ name] . forEach ( item=> {
item ( msg)
} )
}
}
let e1 = new EventHub ( )
e1. add ( 'go' , function ( msg) {
console. log ( msg, '1' ) ;
} )
e1. add ( 'go' , function ( msg) {
console. log ( msg, '2' ) ;
} )
e1. notice ( 'go' , '学习' )