callapplybind的js实现以及应用
js实现call
// example
let obj = {a: 124,b: 'ccc'
};
function fn(c) {return this.a + this.b + this.c;
}
// 使用call是这样转换的
// step 1: 生成新的函数,新的执行上下文(通过在传入对象中增加调用方法)
const obj = {a: 124,b: 'ccc',fn: function(c) {return this.a + this.b + this.c;}
}
// step2: 执行 obj.fn(333);
let res = obj.fn(333);
// step3: obj被改变,得恢复原来的值
delete obj.fn;
Function.prototype.myCall = function(context) {const newContext = context || window;newContext.fn = this;const args = [];for(let i = 1; i < arguments.length; i++) {args.push(arguments[i]);}const res = newContext.fn(...args);delete newContext.fn;return res;
}
console.log(fn.myCall(obj, 'cccc'));
js实现apply
Function.prototype.myApply = function(context, arr) {const newContext = context || window;newContext.fn = this;const args = [];let res;if (!arr) {res = newContext.fn(...args);}else {if (!(arr instanceof Array)) {throw new Error('params must be array');}result = context.fn(...arr);}delete newContext.fn;return res;}
console.log(fn.myApply(obj, ['cccc']));
call & apply
Math.max.apply(null, [3,5,88,2])
在这里,我们看到了一个有趣的现象,在Math.max中可以传入数组
call&apply两大作用:
改变this
借用其他对象的方法
改变this
如何实现Function.prototype.bind()
Function.prototype.bind = function(){var self = this,context = [].shift.apply(arguments);args = [].slice.apply(arguments);return function(){return self.apply(context, [].concat.apply(args, [].slice.apply(arguments)))};
}//执行
var obj = {name: 'yyh'
}
var func = function(a, b, c, d){console.log(this.name);
}.bind(obj, 1, 2);
func(3, 4);
借用其他对象的方法
继承的实现
var aFn = function(){this.name = 'yyh'
}
var bFn = function(){aFn.apply(this, arguments);
}
bFn.prototype.getName = function(){return this.name
}
//执行
var b = new bFn();
console.log(b.getName())
能借用数组的方法,Obj.array.push, 需要满足两个条件
- Obj的属性可存取
- length属性可读写
var a = {c:3};
[].push.apply(a, [3,4,5])
console.log(a)
callapplybind的js实现以及应用相关推荐
- 在js中使用HashMap数据结构,在js中使用K,V数据结构
首先是定义一个HashMap方法,做基类(复制在js中即可,然后引用) //简单的哈希表,begin function HashMap() {/** Map 大小 * */var size = 0;/ ...
- js校验复选框(多选按钮)是否被选中的方法
js校验复选框是否被选中的方法 方法一:(使用下标进行标记) if ($("#checkbox-id")get(0).checked) {// do something } 方法二 ...
- form表单提交前进行ajax或js验证,校验不通过不提交
在使用form表单进行提交数据前,需要进行数据的校验->表单的校验(如:两次密码输入是否相同)+后台数据的校验(如:账号是否存在),这个时候,如果哪步校验不通过,表单将停止提交,同时避免后台主键 ...
- 终止js程序执行的方法
js终止程序执行的方法共有三种 (一)在function里面(普通js方法) (1)return; (2)return false; (二)非function方法里面(如ajax方法) alert(& ...
- JS Uncaught SyntaxError:Unexpected identifier异常报错原因及其解决方法
最近在写ajax的时候,调用js方法,遇到了Uncaught SyntaxError:Unexpected identifier异常报错,开始搞不清原因,很苦恼. 以为是js方法参数个数和长度的问题, ...
- 用js方法做提交表单的校验
基础知识: 原始提交如下: <form action="<%=basePath %>puser/register" method="post" ...
- 【JavaScript总结】JavaScript语法基础:JS高级语法
作用域链: 1.JS中只有函数能够限定作用域的范围: 2.变量处理在制定的函数范围内,还有一个特殊的作用域,就是没有用var 声明的全局作用域 3.js中的作用域链是为了清晰的表示出所有变量的作用范围 ...
- 【JavaScript总结】JavaScript语法基础:JS编码
运算符 数学:+. -. *. / 逻辑:>. < .>= .<=. == . !=.&&.|| . === .!==(完全等于) 对象相关 new delet ...
- js获取html代码中所有图片地址
/** * JS获取html代码中所有的图片地址 * @param htmlstr * @returns imgsrcArr 数组 */ function getimgsrc(htmlstr) { v ...
最新文章
- BCVP开发者说第5期:QuartzCore.Blazor
- 广州.net俱乐部12月份ABP框架活动场地征集、志愿者征集、合作讲师\副讲师征集...
- RandomAccess接口
- 团队作业—第二阶段08
- 网络和新媒体能申请计算机硕士吗,网络与新媒体专业可以报考公务员吗
- oracle 表空间达到32g,oracle表空间到32G后扩容
- VMware Workstation 12 安装小于4GB的GHOST 64位win7系统
- 酷柚易汛工资条代码全开源,方便二次开发
- segger公司调试cortex-m内核出现hardfault的方法
- ahk写入excel单元格_【进阶】Excel 自动化教程
- 输入输出工具技术(ITTO)要背吗?——软考高项笔记8
- 信号与系统--幅度谱和相位谱
- 【全面总结】大厂测试开发面试常见面试题101道
- android双系统切换软件,可一键切换安卓/Win!双系统设备涌现CES
- 智能芯片与系统基础知识(AI芯片)
- 【机器学习实战】构建/绘制决策树(ID3/C4.5)
- IC EMC(集成电路电磁兼容)测试标准介绍
- 15单片机通过WIFI模块ESP8266实现手机远程监控可燃气体浓度
- WORD自动编号的图表标签重新编号
- Kali下面装goldendict词典的安装和添加词典文件
热门文章
- boost::hana::count用法的测试程序
- BOOST_CURRENT_FUNCTION宏用法的测试程序
- boost::fusion::result_of::as_map用法的测试程序
- boost::fusion::flatten用法的测试程序
- boost::gregorian模块实现自年初以来的天数的测试程序
- boost::convert模块实现lexical_cast的测试程序
- 使用Boost.Compute类在GPU上设置和运行简单的矢量加法内核
- VTK:可视化算法之DecimateFran
- VTK:Render之RenderView
- VTK:PolyData之ReverseSense