BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / www-technology / #35295同步于 2016/4/7
该镜像源已超过 30 天没有更新,可能在源站已被删除。
WWWTechnology机器人发帖

啥叫做js解绑定包装器?有啥用?

ztinpn
2016/4/7镜像同步11 回复
如图。
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
h452114240机器人#1 · 2016/4/7
这个好像是用来函数之间传递参数的,然后call和apply这种是用来调用别的方法,动态改变某个类的某个方法的运行环境,apply还有一个妙用是用来将数组变成一个一个参数。解绑定?解arguments类数组?还是解这个方法的运行环境?不懂帮顶 发自「贵邮」
AlstonLYG机器人#2 · 2016/4/7
看背景颜色就看出来是 js garden, 哈哈 我觉得是翻译有些问题吧,至少和原版不一样,而且用例也改了. 给你贴一下这部分的原文, 主要是译者注上边的那段 Another trick is to use both `call` and `apply` together to turn methods - functions that use the value of `this` as well as their arguments - into normal functions which only use their arguments. function Person(first, last) { this.first = first; this.last = last; } Person.prototype.fullname = function(joiner, options) { options = options || { order: "western" }; var first = options.order === "western" ? this.first : this.last; var last = options.order === "western" ? this.last : this.first; return first + (joiner || " ") + last; }; // Create an unbound version of "fullname", usable on any object with 'first' // and 'last' properties passed as the first argument. This wrapper will // not need to change if fullname changes in number or order of arguments. Person.fullname = function() { // Result: Person.prototype.fullname.call(this, joiner, ..., argN); return Function.call.apply(Person.prototype.fullname, arguments); }; var grace = new Person("Grace", "Hopper"); // 'Grace Hopper' grace.fullname(); // 'Turing, Alan' Person.fullname({ first: "Alan", last: "Turing" }, ", ", { order: "eastern" });
AlstonLYG机器人#3 · 2016/4/7
我也不是完全的理解这段代码, 大概的意思就是实现了最后两行的功能. 在最后一行调用方式里,第一个参数传进去后,最后被 .call.apply 那句执行, 调用后 somehow 就在那个 prototype.fullname 里能读出来是 this "解绑定包装器" 的意思我的理解就是把本来用 this 的函数实现不使用 this. 也就是上边我贴的原文的开头那两行的说法.
AlstonLYG机器人#4 · 2016/4/7
我觉得我好想明白了. grace.fullname() 没有什么特别,用 prototype 里边的 fullname(), 里边使用 this 来指代 Person.fullname(...) 想做的事情就是, 利用 apply/call 能传 context 的特性, 把 this 传进去. 但是这个例子的特别之处是在于不是传进去一个已有的某个 context(this), 而是传进去一个自己写的 object ({first: Alan, last: Turing}). (因为this 本身也是 object, 所以参数自己写个 object 也没啥问题) 这样当这个自己写的 object 用 apply 传进去以后, 执行了本来的 prototype.fullname(), 正常从这个传进来的 this (就是 alan turing)里读出来 this.first 和 this.last ,加上其他的内容返回全名. 整个代码最复杂的觉得是这句 return Function.call.apply(Person.prototype.fullname, arguments); 这句的神奇之处就是"译者注"的部分. 不过我查了 MDN, 没有查到 Function constructor 上可以用 call, 也没有查到 call.apply 的文档,希望有人能给出来. 暂且就相信译者说的了. 从这个代码的实现和译者注,这句代码的作用就是分解了 arguments. 整个Person.fullname 执行的时候,参数是3个, 也就是上边的这个 arguments 是包含了我们的 object, 以及后边两个控制名字格式的参数. Function.call.apply(Person.prototype.fullname, arguments); 做到的是 Person.prototype.fullname.apply(arguments里的第一个参数- object, 其他参数) 也就是译者注说的. 译者注那里的第一行 Array.prototype.slice.call(arguments); 是因为 arguments 不是真的是一个 array. (arguments这个章节开头有详细说明) 我感觉我写的乱七八糟的...
ztinpn机器人#5 · 2016/4/8
感谢!今天我再研究下。欢迎加群: 【 在 AlstonLYG (AlstonLYG) 的大作中提到: 】 : 我觉得我好想明白了. : grace.fullname() 没有什么特别,用 prototype 里边的 fullname(), 里边使用 this 来指代 : ...................
yunbiquan机器人#6 · 2016/4/9
Function.call.apply(Person.prototype.fullname, arguments)这句我的理解是: 将函数的call方法用apply方法指定到Person.prototype.fullname环境里执行。 apply方法会将arguments数组当做参数传给call方法,而call方法的第一个参数就是调用call方法的函数的执行环境,即this,在这里就是arguments[0]。
ztinpn机器人#7 · 2016/4/9
解绑定?包装器?这俩啥意思啊 【 在 yunbiquan (SICE敢死队||有理想敢担当勇创新) 的大作中提到: 】 : Function.call.apply(Person.prototype.fullname, arguments)这句我的理解是: : 将函数的call方法用apply方法指定到Person.prototype.fullname环境里执行。 : apply方法会将arguments数组当做参数传给call方法,而call方法的第一个参数就是调用call方法的函数的执行环境,即this,在这里就是arguments[0]。
dcy0701机器人#8 · 2016/4/9
我觉得你可以试一下你的猜想。。。 比如:Function.prototype.call==Function.call 这两个方法是一个指向。。。 类似这两个也是。。Function.prototype.call.__proto__==Function.prototype 所以call和apply就能按照你的想法理解了。。。 我还有一点见解是 one.prototype.method.call(o,args)==o.method(args)的话, 前提是o是one的一个实例。 或者o的原型链上有method方法? 类似 [].push.call(arr1,arr2)==arr1.push(...arr2) 不知道这个结论是否正确。 【 在 AlstonLYG 的大作中提到: 】 : 我觉得我好想明白了. : grace.fullname() 没有什么特别,用 prototype 里边的 fullname(), 里边使用 this 来指代 : Person.fullname(...) 想做的事情就是, 利用 apply/call 能传 context 的特性, 把 this 传进去. 但是这个例子的特别之处是在于不是传进去一个已有的某个 context(this), 而是传进去一个自己写的 object ({first: Alan, last: Turing}). (因为this 本身也是 object, 所以参数自己写个 object 也没啥问题) : ...................
lpy0机器人#9 · 2016/4/9
我说下我的理解哈,举个例子吧 Array.prototype.get2nd = function () { return this[1] } 在Array的prototype上添加一个函数get2nd,获取数组的第二个元素,正常情况下我可以这么用: var a = [1,2,3,4,5] console.log( a.get2nd() ) // 2 要是我想把这个函数用在arguments上,就得这样: var func = function () { return Array.prototype.get2nd.call(arguments) } console.log( func(1,2,3) ) // 2 代码里的那一长串很不好看,我想把它封装一层,可以这样做: Array.get2nd = function () { var args = Array.prototype.slice.call(arguments); return Array.prototype.get2nd.apply(args[0], args.slice(1)); } 然后使用的时候就是这样的: var func = function () { return Array.get2nd(arguments) } console.log( func(1,2,3) ) // 2 上面代码里的Array.get2nd就是《JavaScript秘密花园》里所说的 解绑定包装器,本来Array.prototype.get2nd正常使用是用在Array对象上的,即this绑定的是Array对象,而包装后的Array.get2nd可以用在任何 类数组 的元素上,就比如上面提到的arguments,即this可以为我想指定的任何变量 以上是我自己的理解,有什么地方不妥,一起讨论哈~~ 【 在 ztinpn 的大作中提到: 】 : 如图。