测的是v地方vwd
bind方法模拟
在不支持ES5的浏览器里模拟bind方法
几个注意地方:
1.var aArgs=Array.prototype.slice.call(arguments,1);//这里的arguments是相对function(oThis)而言的,也即对应的是oThis这个参数,这个oThis又是对应bind()里面的参数的,由于bind()第一个参数是对象,后面还可以是用于currying的参数,所以通过slice将后面的参数获取。由于arguments不是标准的数组,需通过数组原型链的调用来使用slice方法。
2.aArgs.concat(Array.prototype.slice.call(arguments)) //这里的arguments是对应fBound=function()这个匿名函数的,而fBound作为最后的返回,对应的是函数bind后赋给的变量(函数),后者再次调用时传入的参数就是这里的arguments,将上面currying的参数并上后面再传入的参数,才组成最开始的函数的参数this/fToBind。
3.fNOP空对象是为了作为通过new之后消除bind作用后函数中this指向空对象的原型链准备。而通过this instanceof fNOP来判断是否使用了new,并决定将对象bind上。没用new,则判断为false,bind(oThis);否则为true,即使用new,函数中this指向空对象。
bind方法
不同的调用方法下,this 指向不同的值
module.getX(); //this 指向module,返回 81
var getX = module.getX;
getX(); // this 指向 全局变量,返回9
var boundGetX = getX.bind(module);
boundGetX(); // this 被 bind 向 module,返回81
重点!
这里绿色的this的问题 指的是 bind后函数执行时的this
这里解释了 为什么 this instanceof fNOP =>true!
bind的实现
非常重要!! 需要多看
bind的实现中 第三行的this对应的是Function 而不是Function.prototype (再看几分钟之后明白了) 因为再bind应用时 是通过 "函数.bind"来实现的 所有这里的this是函数而不能是其他
这里最后new func()得到的对象只有b一个属性 没有a属性(测试环境Node12.13)
柯里化 实例
一般模式下 如果apply/call 的第一个参数是null/undefined 那么函数的this值是全局对象
严格模式下 上面的情况 this会是null/undefined
经测试 bind也是同理(Node环境下)
call和apply的第一个参数会被强制转为对象类型
严格模式下('use strict') 通过arguments设置参数值是无效的
同时 严格模式下 arguments.callee也是无效的
arguments 对没有传参的参数 进行赋值是无效的 (即没有绑定关系) [具体看视频]
arguments可以像数组一样通过[数字]进行寻址 赋值
call和apply方法(window)
func()与new func()的区别,func()是普通的类函数调用,得到return返回值,而new func()表示构造一个对象,如果有return object,则返回object,如果不是return object,eg,return 基本类型,没有return则返回空的this对象。
bind用法:
实现不同页面otherOptions不同,其它参数相同。
bind的柯里化功能的实际应用场景
可能在不同的页面我们需要获取不同的配置,但个别页面的配置又非常相似,比方说A、B、C、D四个页面,都有颜色、大小、其他一些配置信息,但A和B两个页面但颜色和大小都是“#CC0000”和“1024*768”,只有这个其他是不一样但配置。所以我们可以通过bind的柯里化功能,设置一个默认的配置(colors="#CC0000",size="1024*768"),在A页面只要传入最后一个参数defaultConfig("123"),在B页面只要传入最后一个参数defaultConfig("456")
bind的柯里化功能
声明函数add,形参a、b、c,返回三个数之和
var func=add.bind(undefined,100)
undefined:这里不需要改变this指向,所以默认传了undefined
100:赋值给a,a=100
所以func(1,2)这里相当于将1赋值给了b,2赋值给了c,因此func(1,2)=100+1+2=103
var func2=func.bind(undefined,200)
undefined:未改变this指向
200:赋值给b(因为a已被赋值),b=200
所以func2(10)这里相当于将10赋值给了c,因此func2(10)=100+200+10=310
声明一个函数foo,可以通过foo.length获取形参个数(x、y、z三个形参),foo.name获取函数名,arguments.length获取实参个数(这里实参为x=1,y=2两个实参)
若通过arguments[0]进行赋值操作,此时garguments[0]就是实参x,因此也同样会对x值进行修改
需要注意的是,这里未传入z参数,通过arguments[2]去访问的时候相当于没有绑定关系,此时对z进行赋值是不会生效的;另外还要注意严格模式下与一般模式下的区别
obj.call()
obj.apply()
obj.bind()
obj.bind()//绑定this
currying的意义 08:00
使用new则构造函数必须return一个对象,如果不是则return this;10:00
函数科里化
拆分currying
currying拆分
'use strict' 严格模式下 参数不会被修改
aguments
bind方法模拟,没理解
func.bind() 重复传入一些相同的参数时,可以使用bind;
第一个传入为this,不需要可传null;
bind方法的两个功能:绑定this,函数拆分,提供额外的函数,后面的补充剩余的参数就可以了
通过bind方法改变this
光圈处的this公指向全局对象,也就是9