-
-
Notifications
You must be signed in to change notification settings - Fork 236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
call apply bind #30
Comments
Function.prototype._call = function (obj, ...args) {
!obj && (obj = globalThis);
// this代表要执行的函数
obj._fn = this;
const res = obj._fn(...args);
delete obj._fn;
return res;
};
Function.prototype._apply = function (obj, args) {
// 第二个参数必须为数组或类数组对象, 否则初始化为空对象
const arr = [];
for (let i = 0; i < args?.length; ++i) {
arr.push(args[i]);
}
return this._call(obj, ...arr);
};
Function.prototype._bind = function (obj, ...args1) {
!obj && (obj = globalThis);
return (...args2) => {
obj._fn = this;
const res = obj._fn(...[...args1, ...args2]);
delete obj._fn;
return res;
};
}; |
|
// 该代码为上面同学提交的,虽然考虑到了边界条件,更加严谨,但是是有问题的,会使始终指向全局对象window
// 问题就出在这个箭头函数,因为箭头函数的特性,会无法获得到正确的this,即调用call的函数
// !!!处理方式:更改为function(){}即可
Function.prototype._myCall = (thisArg, ...args) => {
thisArg =
thisArg !== null && thisArg !== undefined ? Object(thisArg) : window;
let fn = Symbol();
thisArg[fn] = this;
const res = thisArg[fn](...args);
delete thisArg[fn];
return res;
};
// 同理
Function.prototype._myapply = (thisArg, args = []) => {
thisArg =
thisArg !== null && thisArg !== undefined ? Object(thisArg) : window;
let fn = Symbol();
thisArg[fn] = this;
const res = thisArg[fn](...args);
delete thisArg[fn];
return res;
};
// 同理
Function.prototype._mybind = (thisArg, ...args) => {
let fn = this;
return (...args) => {
return fn._myCall(thisArg, ...args);
};
};
//最好使用symbol进行处理一下,以及对于apply传递的数组考虑一下为空的情况 |
收到,已改正,感谢 |
Function.prototype.myCall = function(context, ...args) {
context = context || window;
const fn = Symbol();
context[fn] = this;
const result = context[fn](...args);
delete context[fn];
return result;
}
Function.prototype.myApply = function(context, args) {
context = context || window;
const fn = Symbol();
context[fn] = this;
const result = context[fn](...args);
delete context[fn];
return result;
}
Function.prototype.myBind = function(context, ...args) {
const self = this;
return function(...args2) {
return self.apply(context, args.concat(args2));
}
} |
用Object.create继承context也许可以避免污染原来的context |
Function.prototype.myapply = function (context, args) {
context = context || window;
args = args || [];
const key = Symbol();
context[key] = this;
const res = context[key](...args); //扩展运算符对参数进行深拷贝的浅层拷贝
delete context[key];
return res;
};
Function.prototype.mycall = function (context, ...args) {
context = context || window;
args = args || [];
const key = Symbol();
context[key] = this;
const res = context[key](...args);
delete context[key];
return res;
};
Function.prototype.mybind = function (context, ...args) {
let self = this;
args = args || [];
return function (...newargs) {
const key = Symbol();
context[key] = self;
const res = context[key](...args, ...newargs);
delete context[key];
return res;
};
}; |
Function.prototype.myCall = function (context, ...args) {
context = context || window
args = args || []
const key = new Symbol()
context[key] = this
const res = context[key](...args)
delete context[key]
return res
}
Function.prototype.myApply = function (context, args) {
context = context || window
args = args || []
const key = new Symbol()
context[key] = this
const res = context[key](...args)
delete context[key]
return res
}
Function.prototype.myBind = function (context, ...args) {
let self = this
args = args || []
return function (...newargs) {
const key = Symbol()
context[key] = self
const res = context[key](...args, ...newargs)
delete context[key]
return res
}
} |
|
前面有一个bind写错了 |
这个更复杂点,只因规范要求 Function.prototype.myBind = function (that, ...partArgs) {
var F = this
var Prototype = F.prototype
var boundFunction = function bound(...newArgs) {
var args = [...partArgs, ...newArgs]
/**
* 若被 new 调用时,this 为即将生成的实例 bound,走 new F(...)
*/
return this instanceof boundFunction ? new F(...args) : F.myApply(that, args)
}
if (Prototype && typeof Prototype === 'object') boundFunction.prototype = Prototype
return boundFunction
} |
// es6中globalThis代指当前环境全局对象
Function.prototype._call = function (context, ...args) {
if (!context) context = globalThis;
context._fn = this;
const result = context._fn(...args);
delete context._fn;
return result;
};
Function.prototype._apply = function (context, args) {
if (!context) context = globalThis;
context._fn = this;
const result = context._fn(...args);
delete context._fn;
return result;
};
Function.prototype._bind = function (context, ...args1) {
if (!context) context = globalThis;
let _this = this;
return function (...args2) {
context._fn = _this;
let result = context._fn(context, ...args1, ...args2);
delete context._fn;
return result;
};
}; |
Function.prototype.Mycall = function (ctx, ...args) {
ctx = (ctx === undefined || ctx === null) ? (window || global) : Object(ctx);
const fn = this;
const key = Symbol('fn');
Object.defineProperty(ctx, key, {
enumerable: false,
value: fn
})
const result = ctx[key](...args);
delete ctx[key];
return result;
}
Function.prototype.MyBind = function (ctx, args) {
ctx = (ctx === undefined || ctx === null) ? (window || global) : Object(ctx);
const fn = this;
const key = Symbol('fn');
Object.defineProperty(ctx, key, {
enumerable: false,
value: fn
})
const result = ctx[key](...args);
delete ctx[key];
return result;
}
Function.prototype.MyBind = function (ctx, ...args) {
ctx = (ctx === undefined || ctx === null) ? (window || global) : Object(ctx);
const fn = this;
const key = Symbol('fn');
return function (...args2) {
let result = null;
Object.defineProperty(ctx, key, {
enumerable: false,
value: fn
})
if (new.target) {
result = new ctx[key](...args, ...args2)
}
else {
result = ctx[key](...args, ...args2)
}
delete ctx[key];
return result;
}
} |
The text was updated successfully, but these errors were encountered: