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. 从0开始学习Hadoop(1) 环境准备 Win7环境+VirtureBox+Ubuntu

    虚拟机:VirtureBox 3.18 下载地址: https://www.virtualbox.org/ 操作系统:Ubuntu  版本:ubuntu-15.04-desktop-amd64.iso ...

  2. 表单中的readOnly 和disabled

    readonly和Disabled是用在表单中的两个属性,它们都能够做到使用户不能够更改表单域中的内容.但是它们之间有着微小的差别,总结如下: disabled也可以禁用按钮和链接: <butt ...

  3. MHA高可用 MHA+Keepalive

    MHA高可用 MHA简介 MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebo ...

  4. (博弈论 高精度小数)51NOD 1185 威佐夫游戏 V2

    有2堆石子.A B两个人轮流拿,A先拿.每次可以从一堆中取任意个或从2堆中取相同数量的石子,但不可不取.拿到最后1颗石子的人获胜.假设A B都非常聪明,拿石子的过程中不会出现失误.给出2堆石子的数量, ...

  5. [ZPG TEST 110] 多边形个数【DP】

    1. 多边形个数 (polygons.pas/c/cpp) [问题描述] 给定N线段,编号1到n.并给出这些线段的长度,用这些线段组成一个K边形,并且每个线段做多使用一次.若使用了一条不同编号的线段, ...

  6. Service官方教程(3)Bound Services

    Bound Services 1.In this document The Basics Creating a Bound Service Extending the Binder class Usi ...

  7. 安装Kube

    安装Docker yum install -y docker 加速Docker DOCKER_MIRRORS="https://5md0553g.mirror.aliyuncs.com&qu ...

  8. Oracle的一些名词和概念

    1.数据库 这里的数据库不是通常情况下我们所说的数据库,而是一个Oracle的专业名词.它是磁盘上存储数据的集合,在物理上表现为数据文件. 日志文件和控制文件等,在逻辑上以表空间形式存在.使用时,必须 ...

  9. Java_JDBC连接数据库_使用读取配置文件的方式

    package com.homewoek3_4.dao; import java.io.IOException; import java.io.InputStream; import java.sql ...

  10. AJPFX:关于面向对象及java的一些机制的思考

    1.变量的作用域和生命周期什么关系? 2.java除了在类体和方法体(包括参数)中可以声明变量外,其他位置一定不可以声明变量吗?比如高级别的应用里是不是有例外呢? 3.java源文件中代码的组织方式一 ...