我是歌谣 放弃很容易 但是坚持一定很酷 微信公众号关注小歌谣一起学习前后端知识
闲来无事做 不如敲代码
今天讲一下js里面的call
apply和bind和typeof方法
的手动封装
由于最近比较忙
但是有时间
就会记录一下平时学习工作的一些代码用来分享
这边就不直接多说开始我们的直接代码书写表演
如果有什么不清楚的地方
可以自己进行一个观察讨论
这个代码是对js进行的相关语法进行的一个封装
顺便对于vite2.0做了一个简单的一个学习
vite2.0相对于webpack打包工具拥有自己的特点
我是歌谣 放弃很容易 但是坚持一定很酷
const utilsModule = ((Function) => {
/**
// context
Function.prototype.myCall = function (ctx) {
// ctx => { a: 1, b: 2 }
// this => test => this => ctx
// ctx => object
// ctx.test => test -> this => ctx
ctx = ctx ? Object(ctx) : window;
// originFn & test -> 一个内存地址
ctx.originFn = this; // 引用
var args = [];
// 拿到myCall的第二个参数开始到结束的所有参数作为test的实参列表
for (var i = 1; i < arguments.length; i ++) {
// args + 字符串 -> args 展开平铺到fn的实参中去
args.push('arguments[' + i + ']');
}
// ctx.originFn([arguments[1], arguments[2]]);
// ctx.originFn(['arguments[1]', 'arguments[2]']);
// 'ctx.originFn([arguments[1], arguments[2]])'
var ret = eval('ctx.originFn(' + args + ')')
delete ctx.orgiinFn;
return ret;
}
Function.prototype.myApply = function (ctx, args) {
ctx = ctx ? Object(ctx) : window;
ctx.originFn = this;
if (typeof args !== 'object' && typeof args !== 'function') {
throw new TypeError('CreateListFromArrayLike called on non-object');
}
if (!args || typeOf(args) !== 'Array') {
return ctx.originFn();
}
var ret = eval('ctx.originFn(' + args + ')');
delete ctx.originFn;
return ret;
}
Function.prototype.myBind = function (ctx) {
var originFn = this,
// bind传递的test的参数
args = [].slice.call(arguments, 1),
// 原型传递中介函数
_tempFn = function () {};
var newFn = function () {
// 返回的新函数t的参数列表
var newArgs = [].slice.call(arguments);
// 如果new t, this -> newFn构造出来的,实例化了,this -> newFn的实例 : ctx
return originFn.apply(this instanceof newFn ? this : ctx, args.concat(newArgs));
}
// 将test.prototype => 中介函数的原型属性
_tempFn.prototype = this.prototype;
// 讲中介函数的实例化对象 => newFn的原型属性
newFn.prototype = new _tempFn();
return newFn;
}
function typeOf (value) {
if (value === null) {
return 'null';
}
// ({}).toString.call(value) -> [object Object]
// var types = {
// '[object Object]': 'Object',
// '[object Array]': 'Array',
// '[object Number]': 'Number',
// '[object String]': 'String',
// '[object Boolean]': 'Boolean'
// };
// if (typeof(value) === 'object') {
// var res = ({}).toString.call(value); //[object Object]
// var type = types[res]
// }
return typeof(value) === 'object' ? {
'[object Object]': 'Object',
'[object Array]': 'Array',
'[object Number]': 'Number',
'[object String]': 'String',
'[object Boolean]': 'Boolean'
}[({}).toString.call(value)] : typeof(value);
}
// var test = myNew(Test, 1, 2);
function myNew () {
var constructor = [].shift.call(arguments),
_this = {};
_this.__proto__ = constructor.prototype;
var res = constructor.apply(_this, arguments);
return typeOf(res) === 'Object' ? res : _this;
}
function instanceOf (target, type) {
type = type.prototype;
target = target.__proto__;
while (true) {
if (target === null) {
return false;
}
if (target === type) {
return true;
}
target = target.__proto__;
}
}
return {
typeOf,
myNew,
instanceOf
}
})(Function);
export default utilsModule;
我是歌谣 放弃很容易 但是坚持一定很酷 一起成为前端大佬 谢谢
浙公网安备 33010602011771号