JavaScript Patterns 6.7 Borrowing Methods
Scenario
You want to use just the methods you like, without inheriting all the other methods that you’ll never need. This is possible with the borrowing methods pattern, which benefits from the function methods call() and apply().
// call() example notmyobj.doStuff.call(myobj, param1, p2, p3); // apply() example notmyobj.doStuff.apply(myobj, [param1, p2, p3]);
Example: Borrow from Array
// Example for calling the slice
function f() {
var args = [].slice.call(arguments, 1, 3);
return args;
}
// example
f(1, 2, 3, 4, 5, 6); // returns [2,3]
Borrow and Bind
When borrowing methods either through call()/apply() or through simple assignment, the object that this points to inside of the borrowed method is determined based on the call expression. But sometimes it’s best to have the value of this “locked” or bound to a specific object and predetermined in advance.
var one = {
name: "object",
say: function (greet) {
return greet + ", " + this.name;
}
};
var two = {
name: "another object"
};
var say = one.say;
// passing as a callback
var yetanother = {
name: "Yet another object",
method: function (callback) {
return callback('Hola');
}
};
one.say('hi'); // "hi, object"
one.say.apply(two, ['hello']); // "hello, another object"
say('hoho'); // "hoho, undefined"
yetanother.method(one.say); // "Holla, undefined"
Solution
This bind() function accepts an object o and a method m, binds the two together, and then returns another function. The returned function as access to o and m via a closure. Therefore even after bind() returns, the inner function will have access to o and m, which will always point to the original object and method.
function bind(o, m) {
return function () {
return m.apply(o, [].slice.call(arguments));
};
}
var twosay = bind(two, one.say);
twosay('yo'); // "yo, another object"
Disadvantage
The price you pay for the luxury of having a bind is the additional closure.
Function.prototype.bind()
ECMAScript 5 adds a method bind() to Function.prototype, making it just as easy to use as apply() and call().
var newFunc = obj.someFunc.bind(myobj, 1, 2, 3);
Implement Function.prototype.bind() when your program runs in pre-ES5 environments.
It’s using partial application and concatenating the list of arguments—those passed to bind()(except the first) and those passed when the new function returned by bind() is called later.
var twosay2 = one.say.bind(two);
twosay2('Bonjour'); // "Bonjour, another object"
References:
JavaScript Patterns - by Stoyan Stefanov (O`Reilly)
JavaScript Patterns 6.7 Borrowing Methods的更多相关文章
- JavaScript Patterns 5.3 Private Properties and Methods
All object members are public in JavaScript. var myobj = { myprop : 1, getProp : function() { return ...
- JavaScript Patterns 6.3 Klass
Commonalities • There’s a convention on how to name a method, which is to be considered the construc ...
- JavaScript Patterns 6.2 Expected Outcome When Using Classical Inheritance
// the parent constructor function Parent(name) { this.name = name || 'Adam'; } // adding functional ...
- JavaScript Patterns 5.8 Chaining Pattern
Chaining Pattern - Call methods on an object one after the other without assigning the return values ...
- JavaScript Patterns 5.4 Module Pattern
MYAPP.namespace('MYAPP.utilities.array'); MYAPP.utilities.array = (function () { // dependencies var ...
- JavaScript Patterns 7.1 Singleton
7.1 Singleton The idea of the singleton pattern is to have only one instance of a specific class. Th ...
- JavaScript Patterns 6.6 Mix-ins
Loop through arguments and copy every property of every object passed to the function. And the resul ...
- JavaScript Patterns 6.5 Inheritance by Copying Properties
Shallow copy pattern function extend(parent, child) { var i; child = child || {}; for (i in parent) ...
- JavaScript Patterns 6.4 Prototypal Inheritance
No classes involved; Objects inherit from other objects. Use an empty temporary constructor function ...
随机推荐
- Android一个ListView列表之中插入两种不同的数据
http://www.cnblogs.com/roucheng/ Android一个ListView列表之中插入两种不同的数据 代码如下: public class ViewHolder{ Butto ...
- jQuery的目标
jQuery的开篇声明里有一段非常重要的话:jQuery是为了改变javascript的编码方式而设计的.从这段话可以看出jQuery本身并不是UI组件库或其他的一般AJAX类库.jQuery改变ja ...
- Base64 字符串转图片 问题整理汇总
前言 最近碰到了一些base64字符串转图片的开发任务,开始觉得没啥难度,但随着开发的进展还是发现有些东西需要记录下. Base64 转二进制 这个在net有现有方法调用: Convert.FromB ...
- jquery简单原则器(匹配第一个元素)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 部署Eclipse中的Web项目到Tomcat服务器运行
用Eclipse开发Web项目时,可以通过Tomcat服务器运行Web项目,此时Web项目被部署在[WorkSpace]\.metadata\.plugins\org.eclipse.wst.serv ...
- 高德携手阿里云发布“LBS云”,账户打通只是第一步
位置.游戏.视频,是公认的基于云计算的三大移动端应用方向.而今,LBS云有了更多进展,在高价值应用与云平台之间实现了资源打通和融合,高德迈出了实质性的一步. 高德地图副总裁郄建军(左)与阿里云业务总经 ...
- CXF和spring整合遇到的问题:No bean named 'cxf' is defined
今天在做ws和spring整合的时候,很不幸的遇到了这个问题,百度了好久,竟然没人遇到这个问题,后来谷歌了一下,都是遇到这个问题的了...在看到一篇文章中提到了cxf.xml,所以我果断的打开这个配置 ...
- node.js处理post请求
1.html 2.app.js var http = require('http') var qs = require('querystring') /** * 路由控制的功能 * @param pa ...
- Several ports (8080, 8009) required by Tomcat v6.0 Server at localhost are already in use.
遇到这个问题似然重启是个办法,但是真心好累.. 1.在dos下,输入 netstat -ano|findstr 8080 //说明:查看占用8080端口的进程 显示占用端口的进程 2.在任务管 ...
- java集合-ArrayList
一.ArrayList 概述 ArrayList 是实现 List 接口的动态数组,所谓动态就是它的大小是可变的.实现了所有可选列表操作,并允许包括 null 在内的所有元素.除了实现 List 接口 ...