最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 箭头函数跟普通函数的this

    正文概述 掘金(赵小川)   2021-06-07   564

    箭头函数跟普通函数this的区别

    1. 指向不同
    普通函数的this指向方法调用时的对象,可以通过call,apply,bind来改变this指向
    
    箭头函数不会创建自己的this,他只会从自己作用域的上一层继承this。
    call,aply,bind,不能改变this指向,只能用来传递参数
    
      var obj = {
            a: 10,
            b: () => {
                console.log(this.a) // undefined
                console.log(this) // Window
            },
            c: function () {
                console.log(this.a) // 10
                console.log(this) // {a:10, b:()=>{},c:f()}
            }
        }
        console.log(obj.b())
        console.log(obj.c())
    
    1. 箭头函数没有原型
     var a = () => { }
        console.log('原型', a) // ()=>{}
        console.log('原型', a.prototype) // undefined
    
    1. 箭头函数不能绑定argument,取而代之的事rest参数...来解决
         let A = () => {
             console.log(arguments); // arguments is not defined
          }
            A(1, 2, 3, 4, 5, 8);
       
       let B = (...rest) => {
            console.log(rest); // [1, 2, 3, 4, 5, 8]
            console.log(Object.prototype.toString.call(rest)) // [object Array]
        }
        B(1, 2, 3, 4, 5, 8);
       
    

    这也说明,es6中的rest(...)参数,返回的是一个数组类型,不像arguments返回的是类数组

    1. 箭头函数是匿名函数,不能作为构造函数,不能new
    无法实例化的原因:
    没有自己的this,无法调用call,apply来改变this指向。如果非要改变,那就直接该父类的this
    没有prototype属性,而new命令执行的时候需要将构造函数的prototype赋值给新的对象的_proto
    

    手写call,apply,bind

    // call实现
    Function.prototype._call = function (context, ...args) {
            const fn = Symbol('fn')
            let ctx = context || window
            ctx.fn = this
            let res = args.length > 0 ? ctx.fn(...args) : ctx.fn()
            delete ctx.fn
            return res
        }
        // apply实现
        Function.prototype._apply = function (context, args = []) {
            const fn = Symbol('fn')
            let ctx = context || window
            ctx.fn = this
            if (!(args && args instanceof Array)) {
                throw ('请传入数组')
            }
            let res = args.length > 0 ? ctx.fn(...args) : ctx.fn()
            delete ctx.fn
            return res
        }
        // bind实现
        Function.prototype._bind = function (context, ...args) {
            let that = this
            return function () {
                return that._call(context, ...args)
            }
        }
        var name = "1";
        var obj = {
            name: 2,
            prop: {
                name: 3,
                getName: function (age, s) {
                    return {
                        name: this.name,
                        age: age,
                        s: s
                    }
                }
            }
        }
        console.log(obj.prop.getName(3, 4)); //  3, 3, 4
        console.log(obj.prop.getName.call(obj, 3, 4)); //this是obj 2, 3, 4 
        console.log('_call实现', obj.prop.getName._call(this, 3, 4)); //this是window 1, 3, 4
        console.log('_apply实现', obj.prop.getName._apply(this, [2, 3])); //this是window 1, 2, 3
        let bindHandle = obj.prop.getName._bind(this, 2, 3)
        console.log('bindHandle()', bindHandle())//this是window 1, 2, 3
    

    类数组转化为数组

     let A = function () {
          console.log('类数组', arguments); // Arguments(6) [1, 2, 3]
          console.log('法一', Array.prototype.slice.call(arguments)); // [1, 2, 3]
          console.log('法二', Array.from(arguments)); // [1, 2, 3]
          console.log('法三', [...arguments]); // [1, 2, 3]
      }
      A(1, 2, 3);
    

    行文思考

    1. bind的实现,其实是利用了闭包,和延迟执行(柯里化)这两个特性。

    闭包文章输出地址

    柯里化


    起源地下载网 » 箭头函数跟普通函数的this

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元