zoukankan      html  css  js  c++  java
  • JS apply 和 call 的实现

    很早之前的一篇博客写了bind的实现,是基于apply的,感兴趣的朋友看完这篇文章可以接着看看bind的实现。

    apply 和 call 主要就是传参的区别。这里就不多说了,直接看代码。

        //call 实现
        Function.prototype.myCall = function(context) {
            
            context.fn = this
            
            var args = [...arguments].slice(1)
            
            var result = context.fn(...args)
            
            delete context.fn
            
            return result
        }
    

    实例

       var obj = {
            name: 'hx'
        }
    
        function foo(sex, age) {
            console.log(sex + ' ' + this.name + ' ' + age);
        }
    
        foo.myCall(obj, 'boy', '25');// boy hx 25  

     实现原理:其实就是把fn放在obj下面执行(后面得把obj.fn从obj上删除了,保持obj的孑然之身嘛!),context.fn = this,obj这个对象就不止name属性了吧,多了fn属性,就是函数 foo。然后context.fn()执行的时候,由于fn是context也就   是obj调用的,那么在foo内部执行的时候, this.name就会找到obj的name,变相达成了实现this指向的更改或者说是其他对象的劫持。

       如果上面关于context.fn还不明白的话,那看下面这个

       var a = {
            b:'11',
            c:function () {
                console.log(this,this.b)
            }
        }
        a.c() // 11  

     接着,apply跟call就是在参数arguments上的处理有一点区别而已

        Function.prototype.myApply = function(context) {
    
            var context = context || window
    
            context.fn = this
    
            var result;
    
            // 需要判断是否存储第二个参数,如果存在,就将第二个参数展开
    
            if(arguments[1]) {
                result = context.fn(...arguments[1])
            } else{
                result = context.fn()
            }
    
            delete context.fn
    
            return result
        }
    

     传送门:bind的实现

          

  • 相关阅读:
    利用BitLocker和vhdx创建一个有加密的Win10系统
    macOS 10.12 任何来源
    Xcode 8 GM 编译缺失 /Users/usr/lib/libresolv.9.dylib
    基于inline-block的列表布局
    markdown 的基本操作
    easyui1.32 各种问题汇总
    angular笔记
    underscore 笔记
    我的问道游戏主题皮肤
    在bootstrap ace样式框架上修改的后台管理型模板(Tab页后台管理模板)
  • 原文地址:https://www.cnblogs.com/hjj2ldq/p/9970231.html
Copyright © 2011-2022 走看看