原生js源码之JavaScript的apply方法
apply方法与call方法非常的相似,call的话是可以多个参数的,apply就只能最多2个参数,第一个参数都是绑定对象,第2个则是一个参数列表,语法如下:
Function.apply(object,args)方法能接收两个参数
object:这个对象将代替Function类里this对象
args:这个是数组,它将作为参数传给Function(args-->arguments)
写个简单例子使用一下apply方法
var person={
name:"人类",
sayHi:function(a,b){
var hi=this.name+" 在向你问好!"+a +" " +b;
return hi;
}
}
var pig={
name:'小猪'
}
console.log(person.sayHi.apply(pig,['真的','很舒服']));
输出:小猪 在向你问好!真的 很舒服
可以看到实参是通过Array的方式传入的
我们就在之前myCall的基础上稍作修改就可以了
Function.prototype.myApply=function(){
var ret;
var args=arguments;
if(args.length==0){
return this();//window
}else{
var context,arg,newArgs;
context = args[0];//第一个参数是作为上下文
if(context==null){//处理null 和 undefined
return this();//window
}
if(typeof context!=='object'){
context = {};
}
context[this.name]=this;
var param = args[1]||[];//取到参数数组
if(!(param instanceof Array)){//当第2个参数不是数组的时候抛出错误
throw TypeError("CreateListFromArrayLike called on non-object");
}
var fn = this.name+"(";
for(var i=0,len=param.length;i<len;i++){
arg = param[i];
if(i===0){
fn+="'"+arg+"'";
}else{
fn+=",'"+arg+"'";
}
}
fn +=")";
ret= eval("context."+fn);
}
return ret;
}
下面来验证一下结果:
完整实现如下:
var person={
name:"人类",
sayHi:function(a,b){
return this.name+" 在向你问好!"+a+" "+b;
}
}
var pig={
name:'小猪'
}
Function.prototype.myApply=function(){
var ret;
var args=arguments;
if(args.length==0){
return this();//window
}else{
var context,arg,newArgs;
context = args[0];//第一个参数是作为上下文
if(context==null){//处理null 和 undefined
return this();//window
}
if(typeof context!=='object'){
context = {};
}
context[this.name]=this;
var param = args[1]||[];//取到参数数组
if(!(param instanceof Array)){
throw TypeError("CreateListFromArrayLike called on non-object");
}
var fn = this.name+"(";
for(var i=0,len=param.length;i<len;i++){
arg = param[i];
if(i===0){
fn+="'"+arg+"'";
}else{
fn+=",'"+arg+"'";
}
}
fn +=")";
ret= eval("context."+fn);
}
return ret;
}
console.log(person.sayHi.apply(pig));
console.log(person.sayHi.apply());
console.log(person.sayHi.apply(undefined));
console.log(person.sayHi.apply(null));
console.log(person.sayHi.apply(pig,));
//console.log(person.sayHi.apply(pig,'你好啊'));//CreateListFromArrayLike called on non-object
console.log(person.sayHi.apply(pig,['你好啊','大侠']));
console.log(person.sayHi.apply(pig,null));
console.log("-----------------")
console.log(person.sayHi.myApply(pig));
console.log(person.sayHi.myApply());
console.log(person.sayHi.myApply(undefined));
console.log(person.sayHi.myApply(null));
console.log(person.sayHi.myApply(pig,));
//console.log(person.sayHi.myApply(pig,'你好啊'));//CreateListFromArrayLike called on non-object
console.log(person.sayHi.myApply(pig,['你好啊','大侠']));
console.log(person.sayHi.myApply(pig,null));
打完收工,欢迎指正!!
相关文章
- How to call javascript function on page load in asp.net
- html table表格导出excel的方法 html5 table导出Excel HTML用JS导出Excel的五种方法 html中table导出Excel 前端开发 将table内容导出到excel HTML table导出到Excel中的解决办法 js实现table导出Excel,保留table样式
- ASP.NET Boilerplate 学习 AspNet Core2 浏览器缓存使用 c#基础,单线程,跨线程访问和线程带参数 wpf 禁用启用webbroswer右键菜单 EF Core 2.0使用MsSql/MySql实现DB First和Code First ASP.NET Core部署到Windows IIS QRCode.js:使用 JavaScript 生成
- Javascript中双等号(==)隐性转换机制 JS里charCodeAt()和fromCharCode()方法拓展应用:加密与解密
- js 从数据数组中返回选定的数据元素 JavaScript slice() 方法
- 【Javascript/Vue】如何解决js中超链接跳转到新的页面不被浏览器拦截?(已解决,代码实例,亲测有效)
- 【JS】JavaScript的循环命令示例(for/for each/do while)
- 【JS】js创建Object对象和构造函数的多种方法(综合示例)
- uni-app - 将 base64 图片编码转为 Blob 本地文件路径(把base64类型的图片,转换成blob二进制文件流)适用于 uni-app / vue.js / JavaScript
- JavaScript: 迭代删除数组元素
- 【JavaScript】关于js的一些理解
- 《Windows 8 开发权威指南:HTML5 和JavaScript卷》——1.3 Microsoft Design新特性
- 《Web测试囧事》——1.4 利用JavaScript加载的漏洞提前购买抢购商品
- JS教程之使用 P5.js 构建一个贪吃蛇游戏(教程含源码)
- 浅谈JS之text/javascript和application/javascript
- 聊聊JS动画库:Velocity.js
- Javascript: hash tables in javascript
- JS 将数字字符串数组转为 数字数组 (互换),js获取数组对象中 某一个key的值,js判断一个数组是否包含另一个数组(一维数组)
- JS IOS/iPhone的Safari浏览器不兼容Javascript中的Date()问题的解决方法
- JavaScript是如何工作的: CSS 和 JS 动画底层原理及如何优化它们的性能
- 【cocos2d-js官方文档】五、Cocos2d-JS v3.0的新Action API
- Google Code Pretiffy 代码 着色 高亮 开源 javascript(JS)库
- 原生js源码之JavaScript的trim方法
- javascript 的学习笔记(第一天)