当前位置:网站首页>Call, apply, bind rewrite, easy to understand with comments

Call, apply, bind rewrite, easy to understand with comments

2022-07-06 06:46:00 Carpool steed

Don't talk too much nonsense, just go to the code , Please point out any errors and problems
call Realization

;(() => {
    
	Function.prototype.myCall = function (ctx) {
    
		ctx = ctx ? Object(ctx) : window
		//  take   Add an object above the parameter object  ,  So make sure that ctx  It's the object 
		ctx.pointer = this
		//  Declare an empty array 
		const param = []
		for (let i = 1; i < arguments.length; i++) {
    
			param.push(`arguments[${
      i}]`)
		}
		//  Receive the return value of the next norm 
		const ret = eval(`ctx.pointer(${
      param.toString()})`)
		//  Delete the newly added attribute above 
		delete ctx.pointer
		//  Go back out again 
		return ret
	}

	//  test 
	function test() {
    
		console.log(this, arguments)
		return 'value'
	}
	test.myCall({
     a: 1, b: 2 }, ' Parameters 1', ' Parameters 2')
})()

apply Realization

;(() => {
    
	Function.prototype.myApply = function (ctx, args) {
    
		ctx = ctx ? Object(ctx) : window
		let ret
		//  take   Add an object above the parameter object  ,  So make sure that ctx  It's the object 
		ctx.pointer = this
		//  Judge  args  type 
		const type = Object.prototype.toString.call(args).slice(8, -1)
		if (type === 'Array') {
    
			//  Receive the return value of the next norm  ,  utilize  ...  Expand expression expand parameter 
			ret = eval('ctx.pointer(...args)')
			//  Delete the newly added attribute above 
			delete ctx.pointer
		} else if (
			type === 'Null' ||
			type === 'Undefined' ||
			type === 'Function'
		) {
    
			ret = eval('ctx.pointer()')
			//  Delete the newly added attribute above 
			delete ctx.pointer
		} else {
    
			throw new TypeError('CreateListFromArrayLike called on non-object')
		}
		//  Go back out again 
		return ret
	}
	//  test 
	function test() {
    
		console.log(this, arguments)
		return 'value'
	}
	test.myApply({
     a: 1, b: 2 }, function () {
    })
})()

bind Realization : This is a bit hard to understand , Just look at the note number

//  characteristic  :
// 1 . Returns a new function 
// 2. bind ->  The first parameter  ->  change this Point to 
// 3.  Receive parameter separation 
// 4.bind and  call Function parameters are passed in the same way 
// 5.  Instantiate the new function returned  -> this. The point is  test  Constructed instance 
// 6.  Instances should inherit  test  Prototype on constructor 
Function.prototype.myBind = function (ctx) {
    
	// 1. preservation this
	const pointer = this
	// 2. Parameters passed for the first time 
	const params = [].slice.call(arguments, 1)
	//  Create a new intermediate function for   Assignment prototype 
	const _typeFn = function () {
    }
	//  Return new function 
	const newFn = function (param) {
    
		// 3.param  Parameters passed for the second time   utilize  concat Splicing 
		const args = params.concat(param)
		// 4. Call function   If test If there is a return value, you need to return  5. Judge this
		return pointer.apply(this instanceof newFn ? this : ctx, args)
	}
	// 6. Copy prototype 
	_typeFn.prototype = pointer.prototype
	newFn.prototype = new _typeFn()

	return newFn
}

//  test 
function test(user, car) {
    
	console.log(this)
	console.log(user + ' Just bought one ' + car + ' vehicle ')
}
test.prototype.fun = ' Method '
const t = test.myBind({
     a: 1, b: 2 }, ' Zhang San ')
const t1 = new t(' Mercedes ')
console.log(t1)

Try to integrate ideas into development , cheer up !!!

原网站

版权声明
本文为[Carpool steed]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202132003354023.html