var context = {id: 12};
function fun (name, age) {
console.log(this.id, name, age)
}

bind

bind() 方法会创建一个新函数。当这个新函数被调用时,bind() 的第一个参数将作为它运行时的 this,之后的一序列参数将会在传递的实参前传入作为它的参数。

 原生 bind
1. var a = fun.bind(context, 'bind');
2. a(1); // 12, 'bind', 1 :作为普通函数
3. new a('1'); // undefined, 'bind', '1' :作为构造函数

以上例子可以看出

     bind作为普通函数使用时,改变的this的指向,指向context对象;fun函数执行了;传入参数不确定,可以在第一步bind传值,也可以在第二步执行函数fun传值。

     bind最为构造函数使用时,不同点是this指向实例的对象。

bind的实现代码

Function.prototype.mybind = function (context) {
if (this && this.constructor !== Function) // 抛错
throw new Error("Function.prototype.mybind - what is trying to be bound is not callable");
// this =>绑定函数 fun
var self = this;
// 获取mybind函数从第二个参数到最后一个参数
var arg = Array.prototype.slice.call(arguments, 1);
function fbound() {
// 普通函数: this => window 构造函数: this => 实例对象
// 获取mybind返回函数传入的函数
var args = Array.prototype.slice.call(arguments);
self.apply(this instanceof self ? this : context, arg.concat(args));
}
var FNOP = function () {};
FNOP.prototype = this.prototype;
fbound.prototype = FNOP.prototype;
return fbound;
} var a = fun.mybind(context, 'mybind');
a('12') // a: 普通函数
var b = new a(12) // a: 构造函数 b: 实例对象

  兼容写法

Function.prototype.bind = Function.prototype.bind || function () {
……
};

call

  call() 方法在使用一个指定的 this 值和若干个指定的参数值的前提下调用某个函数或方法。

原生 call
1. fun.call(context, 'call', 2) // 12, call, 2

  

call 的实现代码

Function.prototype.mycall = function (context) {
if (this && this.constructor !== Function)
throw new Error(this.name + ".mycall is not a function");
context = context || window;
context.fn = this;
var arg = [];
for (var i =1; i< arguments.length; i++) {
arg.push('arguments[' + i + ']');
}
eval('context.fn(' + arg + ')');
delete context.fn;
} fun.mycall(context, 'mycall', 3); // 12, 'mycall', 3

  

apply

apply与call的实现原理差不多,只是apply第二个参数是数组;

1. fun.apply(context, ['call', '4']) // 12, call, '4'

  

Function.prototype.myapply = function (context, arr) {
if (this && this.constructor !== Function)
throw new Error(this.name + ".myapply is not a function");
context = context || window;
context.fn = this;
var arrs = [];
if (arr && arr.constructor === Array) { // 判断第二个参数是数组类型
for (var i =0; i <arr.length; i++) {
arrs.push('arr[' + i + ']');
}
eval('context.fn(' + arrs + ')');
} else if (!arr) { // 第二个参数不传
delete context.fn();
} else { // 第二个参数不是数组类型
throw new Error ("CreateListFromArrayLike called on non-object");
}
delete context.fn;
} fun.myapply(context, ['myapply', 4]);

  


原生javascript实现call、apply和bind的方法的更多相关文章

  1. <JavaScript> call()、apply()、bind() 的用法

    其实是一个很简单的东西,认真看十分钟就从一脸懵B 到完全 理解! 先看明白下面: 例 1 obj.objAge; obj.myFun() // 小张年龄 undefined   例 2 shows() ...

  2. JavaScript中的apply()方法和call()方法使用介绍

    1.每个函数都包含两个非继承而来的方法:apply()和call(). 2.他们的用途相同,都是在特定的作用域中调用函数. 3.接收参数方面不同,apply()接收两个参数,一个是函数运行的作用域(t ...

  3. 原生javascript 获得css样式有几种方法?

    css 样式分为行内样式和 外部样式: 1.javascript 获得行内样式 : 可以使用  ele.style."属性名称"(如果遇到属性名称带有"-", ...

  4. 【THE LAST TIME】this:call、apply、bind

    前言 The last time, I have learned [THE LAST TIME]一直是我想写的一个系列,旨在厚积薄发,重温前端. 也是给自己的查缺补漏和技术分享. 欢迎大家多多评论指点 ...

  5. Javascript中call,apply,bind方法的详解与总结

    在 javascript之 this 关键字详解 文章中,谈及了如下内容,做一个简单的回顾: 1.this对象的涵义就是指向当前对象中的属性和方法. 2.this指向的可变性.当在全局作用域时,thi ...

  6. JavaScript的动态特性(通过eval,call,apply和bind来体现)

    JavaScript的动态特性(通过eval,call,apply和bind来体现) JavaScript是一种基于面向对象的.函数式的.动态的编程语言.现在发展到已经可以用在浏览器和服务器端了. 这 ...

  7. 简单模拟实现javascript中的call、apply、bind方法

    目录 引子 隐式丢失 硬绑定 实现及原理分析 总体实现(纯净版/没有注释) 写在最后 引子 读完<你不知道的JavaScript--上卷>中关于this的介绍和深入的章节后,对于this的 ...

  8. Javascript中call、apply、bind函数

    javascript在函数创建的时候除了自己定义的参数外还会自动新增this和arguments两个参数 javascript中函数也是对象,call.apply.bind函数就是函数中的三个函数,这 ...

  9. JavaScript 之 call apply bind

    关键字 this 绑定的方法 this的动态切换,固然为JavaScript创造了巨大的灵活性,但也使得编程变得困难和模糊.有时,需要把this固定下来,避免出现意想不到的情况.JavaScript提 ...

随机推荐

  1. splay启发式合并

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1889  Solved: 501[Submit][Sta ...

  2. 520. Detect Capital(检测数组的大小写)

    Given a word, you need to judge whether the usage of capitals in it is right or not. We define the u ...

  3. E20170516-gg

    accelerator  n. 加速器;油门 oscillator  n. 振荡器; 振子; oscillate  vt. 使振荡,使振动  vi. 持续周期性地摆动; frame  n. 框架; 边 ...

  4. bzoj 1061: [Noi2008]志愿者招募【最小费用最大流】

    神奇的建图:连接(s,1,inf,0)(n+1,t,inf,0),对于1~n连接(i,i+1,inf-a[i],0),对于每个志愿者(s,t,c),连接(s,t+1,inf,c). 因为从s开始的流是 ...

  5. 洛谷 P3708 koishi的数学题

    找规律发现\( f[i]=f[i-1]+n-\sum_{i的因数和} \) 一A了深(sh)蓝(ui)题的我被找规律绿题卡死 记得开long long #include<iostream> ...

  6. python之定时器Timer

    timer类 Timer(定时器)是Thread的派生类,用于在指定时间后调用一个方法. 构造方法: Timer(interval, function, args=[], kwargs={})  in ...

  7. 473 Matchsticks to Square 火柴拼正方形

    还记得童话<卖火柴的小女孩>吗?现在,你知道小女孩有多少根火柴,请找出一种能使用所有火柴拼成一个正方形的方法.不能折断火柴,可以把火柴连接起来,并且每根火柴都要用到.输入为小女孩拥有火柴的 ...

  8. 221 Maximal Square 最大正方形

    在一个由0和1组成的二维矩阵内,寻找只包含1的最大正方形,并返回其面积.例如,给出如下矩阵:1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0返回 4. 详见:https://l ...

  9. mysql 的 case when then 用法 和null 的判断

    表:一个表 aa 有两个字段 id 和 sex ,第1条记录的sex 为空串  ('')  第二条记录的sex 为空  (null) 1. 用法: 第一种: select (case 字段名  whe ...

  10. (1) Jenkins + Subversion + Maven + TestNG - 软件

    软件需求 1 Jenkins http://jenkins-ci.org/ 2 Visual SVN Server https://www.visualsvn.com/server/ 3 Tortoi ...