zoukankan      html  css  js  c++  java
  • javascript Function之bind

    前几天看到一个面试题,题目是这样的:

    请你说说对javascript中apply,call,bind的理解?

    首先apply和call是老生常谈的东西,但是对于bind,我愣了下,因为这个词是jquery中使用频率很高的一个方法,用来给DOM元素绑定事件用的。

    为了搞清这个陌生又熟悉的bind,google一下,发现javascript1.8.5版本中原生实现了此方法,目前IE9+,ff4+,chrome7+支持此方法,opera和safari不支持(MDN上的说明)。

    bind的作用和apply,call类似都是改变函数的execute context,也就是runtime时this关键字的指向。但是使用方法略有不同。一个函数进行bind后可稍后执行。

    例子如下:

    var person = {
        name: 'Andrew',
        job: 'web front end developer',
        gender: 'male',
        sayHello: function() {
            return 'Hi, I am ' + this.name + ', a ' + this.job;
        }
    }
        
    console.log(person.sayHello());  // Hi, I am Andrew, a web front end developer
    
    var anotherGuySayHello = person.sayHello.bind({
        name:'Alex',
        job: 'back end C# developer'
    });
    
    console.log(anotherGuySayHello()); // Hi, I am Alex, a back end C# developer
    

    另外带有参数的例子:

    function add(arg1, arg2, arg3, arg4) {
        return arg1 + ' ' + arg2 + ' ' + arg3 + ' ' + arg4;
    }
    var addMore = add.bind({}, 'a', 'b');
    
    console.log(addMore('c', 'd'));  // a b c d
    

    如果你的浏览器暂时不支持此方法,但你又觉得这个很cool,想用,MDN上也给出参考实现, 这个实现很有意思,代码如下:

    if(!Function.prototype.bind) {
        Function.prototype.bind = function(oThis) {
            if(typeof this !== 'function') {
                throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
            }
            
            var fSlice = Array.prototype.slice,
                aArgs = fSlice.call(arguments, 1),
                fToBind = this,
                fNOP = function() {},
                fBound = function() {
                    return fToBind.apply(this instanceof fNOP ? this : oThis || window, aArgs.concat(fSlice.call(arguments)));
                };
            
            fNOP.prototype = this.prototype;
            fBound.prototype = new fNOP();
        
            return fBound;
        };
    }
    

    最后几行代码,通过prototype chain的方式,其中fBound是调用bind函数的子类,为什么这么实现,可以仔细看 fBound = function(){ return ... }这一部分,其中this是运行时决定的,这里主要考虑到如果用new的方式来调用函数(构造函数方式)的情况。

    下面的例子,就能很好的说明这点,为了方便说明,此例子直接来自MDN:

    function Point(x,y) {
        this.x = x;
        this.y = y;
    }
    
    Point.prototype.toString = function() {
        return this.x + ',' + this.y;
    };
    
    var p = new Point(1, 2);
    p.toString();  // 1,2
    
    var emptyObj = {};
    var YAxisPoint = Point.bind(emptyObj, 0);
    
    var axisPoint = new YAxisPoint(5);
    axisPoint.toString();  // 0, 5
    
    axisPoint instanceof Point;     // true
    axisPoint instanceof YAxisPoint;   // true
    

    最后给出文章链接,方便您进一步了解

  • 相关阅读:
    16进制节码解析
    批注:modbus_tkdefines.py
    <20211019> Win10不明原因丢失任务提示栏里的Wifi以及网络任务提示栏logo
    <20210926>log: 运行5年3个月的NAS硬盘更换
    Huggingface中的BERT模型的使用方法
    list变量和dict变量前面加*号
    Linux服务器登录阿里网盘下载和上传文件的方法
    【IDEA与git集成】
    【为什么要用 @param注解】
    【我的编程习惯与开发插件】
  • 原文地址:https://www.cnblogs.com/AndyWithPassion/p/javascript_function_bind.html
Copyright © 2011-2022 走看看