js中bind解析
一、arguments的含义
// arguments 是一个对应于传递给函数的参数的类数组对象
function a(){
console.log(arguments);
}
a(); // Arguments [callee: ƒ, Symbol(Symbol.iterator): ƒ]
a(1,2,3); // Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
二、Function.prototype.bind()
bind()方法主要就是将函数绑定到某个对象,bind()会创建一个函数,函数体内的this对象的值会被绑定到传入bind()中的第一个参数的值,例如:f.bind(obj),实际上可以理解为obj.f(),这时f函数体内的this自然指向的是obj;
var a = {
b: function() {
var func = function() {
console.log(this.c);
}
func();
},
c: 'hello'
}
a.b(); // undefined 这里的this指向的是全局作用域
console.log(a.c); // hello
var a = {
b: function() {
var _this = this; // 通过赋值的方式将this赋值给that
var func = function() {
console.log(_this.c);
}
func();
},
c: 'hello'
}
a.b(); // hello
console.log(a.c); // hello
// 使用bind方法一
var a = {
b: function() {
var func = function() {
console.log(this.c);
}.bind(this);
func();
},
c: 'hello'
}
a.b(); // hello
console.log(a.c); // hello // 使用bind方法二
var a = {
b: function() {
var func = function() {
console.log(this.c);
}
func.bind(this)();
},
c: 'hello'
}
a.b(); // hello
console.log(a.c); // hello
// 分析:这里的bind方法会把它的第一个实参绑定给f函数体内的this,所以里的this即指向{x:1}对象;
// 从第二个参数起,会依次传递给原始函数,这里的第二个参数2即是f函数的y参数;
// 最后调用m(3)的时候,这里的3便是最后一个参数z了,所以执行结果为1+2+3=6
// 分步处理参数的过程其实是一个典型的函数柯里化的过程(Curry)
function f(y,z){
return this.x+y+z;
}
var m = f.bind({x:1},2);
console.log(m(3)); //
// 分析:直接调用a的话,this指向的是global或window对象,所以会报错;
// 通过bind或者call方式绑定this至document对象即可正常调用
var a = document.write;
a('hello'); // error
a.bind(document)('hello'); // hello
a.call(document,'hello'); // hello
三、原生js实现bind方法
// 方法一,只可绑定,不可传参
Function.prototype.my_bind = function(context){
var self = this;
return function(){
self.apply(context,arguments);
}
}
function a(){
console.log(this.name);
}
a(); // ''
var b = {
name: 'apple'
};
a.bind(b)(); // apple
a.my_bind(b)(); // apple
Function.prototype.my_bind = function() {
var self = this, // 保存原函数
context = Array.prototype.shift.call(arguments), // 保存需要绑定的this上下文
// 上一行等价于 context = [].shift.call(arguments);
args = Array.prototype.slice.call(arguments); // 剩余的参数转为数组
return function() { // 返回一个新函数
self.apply(context, Array.prototype.concat.call(args, Array.prototype.slice.call(arguments)));
}
}
function a(m, n, o) {
console.log(this.name + ' ' + m + ' ' + n + ' ' + o);
}
var b = {
name: 'kong'
};
a.my_bind(b, 7, 8)(9); // kong 7 8 9
js中bind解析的更多相关文章
- 【转载】JS中bind方法与函数柯里化
原生bind方法 不同于jQuery中的bind方法只是简单的绑定事件函数,原生js中bind()方法略复杂,该方法上在ES5中被引入,大概就是IE9+等现代浏览器都支持了(有关ES5各项特性的支持情 ...
- mvc的自带json序列化的datetime在js中的解析
默认仅序列化后的日期格式是这样的:'/Date(124565787989)/'(数字随便敲的,数字表示相对于1970年的总毫秒数) 在js中借助eval函数,eval函数的意义:将参数中的字符串当作j ...
- js中bind,call,apply方法的应用
最近用js的类写东西,发现一个无比蛋疼的事,那就是封装的类方法中的this指针经常会改变指向,失去上下文,导致程序错误或崩溃. 比如: function Obj(){ this.type = &quo ...
- js中bind、call、apply函数的用法
最近一直在用 js 写游戏服务器,我也接触 js 时间不长,大学的时候用 js 做过一个 H3C 的 web的项目,然后在腾讯实习的时候用 js 写过一些奇怪的程序,自己也用 js 写过几个的网站.但 ...
- js中bind、call、apply函数的用法 (转载)
最近看了一篇不错的有关js的文章,转载过来收藏先!!! 最近一直在用 js 写游戏服务器,我也接触 js 时间不长,大学的时候用 js 做过一个 H3C 的 web 的项目,然后在腾讯实习的时候用 j ...
- JS中bind、call和apply的作用以及在TS装饰器中的用法
目录 1,前言 1,call 1.1,例子 1.2,直接调用 1.3,将this指向另一个对象 1.4,传递参数 2,apply 2.1,例子 2.2,直接调用 2.3,将this指向另一个对象 2. ...
- js 中bind
function fn(a){ this.innerHTML = a; console.log(this); } //fn("hello"); span1.onclick =fun ...
- js中bind的用法,及与call和apply的区别
call和apply的使用和区别不再做阐述,可以参考我的另一篇随笔<JavaScript中call和apply方法的使用>(https://www.cnblogs.com/lcr-smg/ ...
- 理解js中bind方法的使用
提到bind方法,估计大家还会想到call方法.apply方法:它们都是Function对象内建的方法,它们的第一个参数都是用来更改调用方法中this的指向.需要注意的是bind 是返回新的函数,以便 ...
随机推荐
- CDH5.16.1的Hbase1.2的G1参数配置
1 贴一下自己的G1垃圾收集器参数(region server配置了5G内存) -Xmx5g -Xms5g -XX:MaxDirectMemorySize=5g -XX:+UseG1GC -XX:+U ...
- ThreadPoolExecutor源码分析二
接上文,这里继续分析源码 private static final int COUNT_BITS = Integer.SIZE - 3; private static final int CAPA ...
- linux基础_关机重启注销
1.关机重启命令 (1)shutdown shutdown -h now:表示立即关机 shutdown -h 1:表示1分钟后关机 shutdown -r now:立即重启 (2)halt:就是直 ...
- [HBase]region compaction流程
- 使用WebSocket实现简单的在线聊天室
前言:我自已在网上找好了好多 WebSocket 制作 在线聊天室的案列,发现大佬们写得太高深了 我这种新手看不懂,所以就自已尝试写了一个在线简易聊天室 (我只用了js 可以用jq ) 话不多说,直接 ...
- mysql批量新增和批量删除
首先推荐使用PreparedStatement的批量处理操作. Connection conn = null; PreparedStatement stmt = null; try{ Class.fo ...
- 【Android-自定义控件】SwipeRefreshDemo 下拉刷新,上拉加载
参考:https://github.com/PingerOne/SwipeRefreshDemo 谷歌官方的SwipeRefreshLayout控件,只有下拉刷新功能. 自定义的SwipeRefres ...
- jmeter-post请求自动变成get,提示请求方式错误,修改协议即可
修改协议: http 改为 https 或反之
- Mysql数据库多对多关系未建新表
原则上,多对多关系是要新建一个关系表的,当遇到没有新建表的情况下如何查询多对多的SQL呢? FIND_IN_SET(str,strlist) 官网:http://dev.mysql.com/doc/r ...
- 我带旅游ERP管理系统开发的经历
前言 不怎么会写博文的我也不知道怎么写,但是有冲动让我去记录下我做项目的经历. 项目背景 某旅行社需要一款内部业务管理系统,找了一家外包来开发但最终不是她们想要的,上线的时候很多问题,首先酒店和票务资 ...