1.自己实现一个call
1)利用对象的方式的形式改变this指针  funcion add;  add.call(temObj)
只需要 在temObj对象临时添加一个方法即可
Function.prototype.mycall2=function(context){
context.fn=this;
context.fn();
Reflect.deleteProperty(context,'fn')
}
2)call还可以携带实参传入
利用函数的arguments截取除了第一个即可
Function.prototype.mycall2=function(context){
var args=[];
for(var i=1;i<arguments.length;i++){
args.push('arguments['+i+']')
};
debugger
context.fn=this;
context.fn(args); //但是args是一个类数组
Reflect.deleteProperty(context,'fn')
}
3)实现拆解函数的参数
将args这个类数组拆解为(args[0],args[1],....) Es6可以用扩展运算符
也可以用new Function var result = new Function('context', 'arguments', 'context.fn(' + args + ')')(context, arguments)
Es3可以利用eval语法,eval中,args 自动调用 args.toString()方法;而数组中的toString的效果就是[].join(',')
var temArr=[1,2,3];
temArr.toString(); //1,2,3
temArr.join() //1,2,3
temArr.join=temArr.shift
temArr.toString() //1
最终效果  context.fn(arguments[1], arguments[2], ...);
Function.prototype.mycall2=function(context){
var args=[];
for(var i=1;i<arguments.length;i++){
args.push('arguments['+i+']')
};
context.fn=this;
//context.fn(args);
eval('context.fn('+args+')')
Reflect.deleteProperty(context,'fn')
}

  function test(x,y){
    debugger;
    return console.log(x+y+this.name)
  }

  var temObj={name:'penguin'}

  test.mycall2(temObj,1,2)

4)实现当传null时候this指向window;还有有返回值
Function.prototype.mycall2=function(context){
var context = context || window;
var args=[];
for(var i=1;i<arguments.length;i++){
args.push('arguments['+i+']')
};
context.fn=this;
var result=eval('context.fn('+args+')')
Reflect.deleteProperty(context,'fn')
return result
}

参考:https://github.com/mqyqingfeng/Blog/issues/11

实现一个apply
Function.prototype.myApply=function(context,arr){
var context=context||window;
context.fn=this;
var args=[],result;

    for (var i = 0, len = arr.length; i < len; i++) {
      args.push('arr[' + i + ']');
    }

  if(!arr){
result=context.fn()
}else{
result=eval('context.fn('+args+')');
}
return result;
}
1.自己实现一个bind函数
原理:通过apply或者call方法来实现。
(1)初始版本
Function.prototype.bind=function(obj,arg){
var arg=Array.prototype.slice.call(arguments,1);
var context=this;
return function(newArg){
arg=arg.concat(Array.prototype.slice.call(newArg));
return context.apply(obj,arg);
}
} (2) 考虑到原型链
为什么要考虑?因为在new 一个bind过生成的新函数的时候,必须的条件是要继承原函数的原型
Function.prototype.bind=function(obj,arg){
var arg=Array.prototype.slice.call(arguments,1);
var context=this;
var bound=function(newArg){
arg=arg.concat(Array.prototype.slice.call(newArg));
return context.apply(obj,arg);
}
var F=function(){}
//这里需要一个寄生组合继承
F.prototype=context.prototype;
bound.prototype=new F();
return bound;
}
如何实现sleep的效果(es5或者es6)
(1)while循环的方式
function sleep(ms){
var start=Date.now(),expire=start+ms;
while(Date.now()<expire);
console.log('1111');
return;
} 执行sleep(1000)之后,休眠了1000ms之后输出了1111。上述循环的方式缺点很明显,容易造成死循环。
(2)通过promise来实现
function sleep(ms){
var temple=new Promise(
(resolve)=>{
console.log(111);setTimeout(resolve,ms)
});
return temple
}
sleep(500).then(function(){
//console.log(222)
})
//先输出了111,延迟500ms后输出222 (3)通过async封装
function sleep(ms){
return new Promise((resolve)=>setTimeout(resolve,ms));
}
async function test(){
var temple=await sleep(1000);
console.log(1111)
return temple
}
test();
//延迟1000ms输出了1111 ####(4).通过generate来实现
function* sleep(ms){
yield new Promise(function(resolve,reject){
console.log(111);
setTimeout(resolve,ms);
})
}
sleep(500).next().value.then(function(){console.log(2222)})
Function._proto_(getPrototypeOf)是什么?
获取一个对象的原型,在chrome中可以通过__proto__的形式,或者在ES6中可以通过Object.getPrototypeOf的形式。
那么Function.proto是什么么?也就是说Function由什么对象继承而来,我们来做如下判别。
Function.__proto__==Object.prototype //false
Function.__proto__==Function.prototype//true
复制代码
我们发现Function的原型也是Function。

Function._proto_(getPrototypeOf)是什么?

获取一个对象的原型,在chrome中可以通过__proto__的形式,或者在ES6中可以通过Object.getPrototypeOf的形式。

那么Function.proto是什么么?也就是说Function由什么对象继承而来,我们来做如下判别。

Function.__proto__==Object.prototype //false
Function.__proto__==Function.prototype//true
复制代码

我们发现Function的原型也是Function。

call apply bind sleep的更多相关文章

  1. call,apply,bind的用法

    关于call,apply,bind这三个函数的用法,是学习javascript这门语言无法越过的知识点.下边我就来好好总结一下它们三者各自的用法,及常见的应用场景. 首先看call这个函数,可以理解成 ...

  2. JavaScript中call,apply,bind方法的总结。

    why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之前,通常会有这些问题. var a = { user:"追梦子", fn:f ...

  3. call(),apply(),bind()与回调

    1.call(),apply(),bind()方法 JavaScript 中通过call或者apply用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定 ...

  4. JS 的 call apply bind 方法

    js的call apply bind 方法都很常见,目的都是为了改变某个方法的执行环境(context) call call([thisObj[,arg1[, arg2[,   [,.argN]]]] ...

  5. javascript-this,call,apply,bind简述2

    上节我们一起研究了this这个小兄弟,得出一个结论,this指向调用this所在函数(或作用域)的那个对象或作用域.不太理解的朋友可以看看上节的内容,这次我们主要探讨一下call(),apply(), ...

  6. javascript-this,call,apply,bind简述1

    最近在系统的学习面向对象方面的知识,遇到的最大拦路虎就数this的指向,call,apply,bind函数的使用,单独抽出一天时间把这几个烦人的家伙搞定,去学习更深入的内容. 首先介绍一下this的一 ...

  7. call,apply,bind方法的总结

    why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之前,通常会有这些问题. var a = { user:"追梦子", fn:f ...

  8. JavaScript中call,apply,bind方法的总结

    原文链接:http://www.cnblogs.com/pssp/p/5215621.html why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之 ...

  9. call, apply,bind 方法解析

    call(), apply(),bind() 三者皆为Function的方法 call(),apply()的作用是调用方法,并改变函数运行时的context(作用上下文) bind() 的作用是引用方 ...

  10. JS中call,apply,bind方法的总结

    why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之前,通常会有这些问题. var a = { user: "小马扎", fn: ...

随机推荐

  1. Linux系统下Java开发环境的配置(未完...)

    1.查看jdk版本   java -version 2.将下载好的jdk放在/usr/lib/jvm里(其中jvm是自己起的名)   sudo mv jdk1.8.0_111 /usr/lib/jvm ...

  2. 20175215 2018-2019-2 第五周java课程学习总结

    第六章学习内容 1.接口 使用interface来定义一个接口. 接口体中包含常量的声明(没有变量)和抽象方法两部分.接口体中只有抽象方法,没有普通的方法,而且接口体中所有的常量的访问权限一定都是pu ...

  3. defineProperty和defineProperties介绍

    v-model 实现的原理 angular 是 mvc 的实现原理,ng-model 是靠脏值检测实现的 脏值检测:for 循环一个个对比 vue 靠的是数据劫持 和 发布者,订阅者模式 数据劫持:O ...

  4. 线性回归linear regression(python脚本实现)

    python机器学习-乳腺癌细胞挖掘(博主亲自录制视频) https://study.163.com/course/introduction.htm?courseId=1005269003&u ...

  5. leetcode 215 第K个最大的元素

    此问题可转化为Top K问题进行考虑,当用小顶堆选出K个最大值时,堆顶的元素即为第k大的元素 class Solution { public: int findKthLargest(vector< ...

  6. VueLoaderPlugin作用

    在webpack配置里加入new VueLoaderPlugin, 在plugin里打断点 然后debug: 在这个地方: 可以发现,在webpack初始化的阶段..webpack.js刚开始执行的时 ...

  7. Windows服务器连接

    公司部分服务器是使用的Windows系统,需要远程连接 首先,我们要做的就是打开一个运行界面.按住win+r. 然后,我们在打开一行里输入mstsc. 这个时候我们点击确定,就会弹出一个远程桌面连接的 ...

  8. Message Unable to compile class for JSP

    使用 UniEAPWorkshop_5.0运行4.6 的代码,流程新建时出现的错误 JDK 使用C:\Program Files (x86)\Java\jdk1.7.0_80 tomcat使用 apa ...

  9. 按需加载controller——angular

    一.多视图应用 AngularJS 通过路由支持多视图应用, 可以根据路由动态加载所需的视图.随着视图的不断增加, js文件会越来越多, 而 AngularJS 默认需要把全部的 js 都一次性加载, ...

  10. JavaScript基础修炼(14)

    目录 一. PCM格式是什么 二. 浏览器中的音频采集处理 三. 需求实现 方案1——服务端FFmpeg实现编码 方案2——ScriptProcessorNode手动处理数据流 参考文献 示例代码托管 ...