简要谈谈javascript bind 方法
最近去参加了场面试,跟面试官聊了很多JS基础上的东西,其中有个问题是谈谈对apply、call、bind的理解和区别。顿时一愣,apply、call我知道,经常用的东西,bind是什么鬼!!!好像见过,也瞅过类似的文章,但是...不记得了...难道和jQuery的事件绑定的bind一样...
既然不知道,那就整理总结下啰~
一、apply和call
既然提到提到了这两兄弟,也跟着简单做下知识整理。在javascript中,this的指向是一个经常要处理的问题。比较经典的一个问题就是,document.getElementById太长了,敲着好累好烦,用一个短点的方法,对它进行封装一下,就下面这样,两行代码搞定,多么简单~
<div id="test"></div>
<script>
var getDom = document.getElementById;
console.log(getDom("test"))
</script>
但是。。。调用时,系统提示Uncaught TypeError: Illegal invocation 啊..........这是什么鬼错误 !其实这就是this的问题,使用document.getElementById,函数执行时this指向document,但是使用getDom,函数执行时,this指向的是window。而在getElementById在内核实现中又使用了this,so 就报错了啰!!!
正确的封装方式为:(即用apply/call设定下函数调用时的this指向)
<div id="test"></div>
<script>
var getDom = (function(func){
return function(){
return func.apply(document , arguments);
}
})(document.getElementById);
console.log(getDom("test"))
</script>
总结:apply和call的用法是一致的,就是改变和确定函数执行时的this指向,区别就是apply后一个参数是数组,call后是一堆参数。话不多说,进入正题....
二、bind基本
首先来谈谈它跟apply/call的区别,bind方法返回的是一个函数,不会立即执行,待用()调用时才会执行,而apply/call则是立即执行函数。
MDN的解释是:bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。
接下来用demo简单使用下
1、单纯的绑定this
var person1 = {
name : "sky" ,
getName : function(){
return this.name;
}
}
var person2 = {name : "moon"};
var getName = person1.getName.bind(person2); //绑定person2作为getName函数执行的this
console.log(getName()); //打印的值为moon
这样用法比较简单
2、传参数的形式
var self = {name : "sky" , age: 26}
var getDescription = function(country , city){
console.log("my name is " + this.name + " , my age is " + this.age + " , I'am from " + country + " " + city);
}.bind(self , "China");
getDescription("WuHan"); //my name is sky , my age is 26 , I'am from China WuHan
个人感觉,这种就是相当于通过bind方法预设一些参数,比如此时就是预设的country参数,调用时在传递动态的参数,比如这里的WuHan。通过这样的方式绑定this,配合预设参数,灵活程度十分的高
三、bind的使用场景
水平有限,仅谈谈个人。我在多层函数嵌套的代码编写中,喜欢使用var _this = this;来保存上级函数作用域中的this,这样在内嵌的函数中就是可以用_this获取上级作用域的this。如果用bind则可以换一种方式,具体对比如下:
<div id="test1">test1</div>
<div id="test2">test2</div>
<script>
//旧写法,使用_this保存
var tool1 = {
name: "sky1",
bindEvent: function() {
var _this = this;
document.getElementById("test1").addEventListener("click", function() {
console.log(_this.name)
}, false)
}
}
//新写法,使用bind绑定
var tool2 = {
name: "sky2",
bindEvent: function() {
document.getElementById("test2").addEventListener("click", function() {
console.log(this.name)
}.bind(this), false)
}
}
tool1.bindEvent();
tool2.bindEvent();
</script>
怎么说呢,代码看起来更加优美一些把....我是颜值控
四、bind 兼容性
bind方法是ES5中扩展的方法,所以IE6、7、8均不兼容...整个人都不好了
怎么办呢,网上有一堆的兼容资料,我比较喜欢自己造轮子...其实也蛮简单的,就是apply/call的封装使用,学习嘛,循序渐进的来,分成两步,以下均用skyBind方法表示...
1、仅仅实现修改执行环境即this的功能
Function.prototype.skyBind = function(context){
var func = this; //就是它!!!这个func就是需要执行,且要绑定context的函数!!!!!!
return function(){
return func.apply(context , arguments); //绑定且执行
}
}
var person1 = {
name : "sky" ,
getName : function(){
return this.name;
}
}
var person2 = {name : "moon"};
var getName = person1.getName.skyBind(person2);
console.log(getName()); //打印的值为moon
很简单有没有!!!
2、加入传参的功能
Function.prototype.skyBind = function(){
var func = this , //还是它!!!这个func就是需要执行,且要绑定context的函数!!!!!!
context = [].shift.call(arguments) , //此时传入的参数就不单单有this的指向,还是其他的参数,按规定第一个参数就是执行环境,拿到它
args = [].slice.call(arguments); //arguments具有数组的属性,毕竟JS是个弱类型的语言,但是它毕竟不是数组,用这个方法就是把arguments转换成数组,不用slice换成splice或者其他的都行
return function(){
/* 绑定且执行,执行函数的参数为两个数组的合并
* 这里需要解释的是args是bind绑定时传入的参数,比如下面demo中的China,而下面的arguments则是实际调用时传入的参数WuHan
* */
return func.apply(context , [].concat(args , [].slice.call(arguments) ));
}
}
//demo
var self = {name : "sky" , age: 26}
var getDescription = function(country , city){
console.log("my name is " + this.name + " , my age is " + this.age + " , I'am from " + country + " " + city);
}.skyBind(self , "China");
getDescription("WuHan"); //my name is sky , my age is 26 , I'am from China WuHan
搞定!!!
简要谈谈javascript bind 方法的更多相关文章
- 谈谈javascript数组排序方法sort()的使用,重点介绍参数使用及内部机制?
语法:arrayObject.sort(sortby) 参数sortby可选,规定排序顺序,必须是函数: 注:如果调用该方法时没有使用参数,将按字符编码的顺序进行排序,要实现这一点,首先应把数组的元素 ...
- Javascript中call,apply,bind方法的详解与总结
在 javascript之 this 关键字详解 文章中,谈及了如下内容,做一个简单的回顾: 1.this对象的涵义就是指向当前对象中的属性和方法. 2.this指向的可变性.当在全局作用域时,thi ...
- 如何在JavaScript中正确引用某个方法(bind方法的应用)
在JavaScript中,方法往往涉及到上下文,也就是this,因此往往不能直接引用,就拿最常见的console.log("info…")来说,避免书写冗长的console,直接用 ...
- javascript中函数的call,apply及bind方法
call 方法调用一个对象的一个方法,以另一个对象替换当前对象.call([thisObj[,arg1[, arg2[, [,.argN]]]]])参数thisObj可选项.将被用作当前对象的对象. ...
- 《JavaScript总结》apply、call和bind方法
在JavaScript中,apply.call.bind这个三个方法,它们的作用都是为了改变某个函数运行时的上下文, 也就是改变函数体内的this指向. 在一个函数里,存在“定义时上下文”.“运行时上 ...
- 浅析 JavaScript 中的 Function.prototype.bind() 方法
Function.prototype.bind()方法 bind() 方法的主要作用就是将函数绑定至某个对象,bind() 方法会创建一个函数,函数体内this对象的值会被绑定到传入bind() 函数 ...
- javascript原生bind方法详解
bind()方法,是javascript原生的函数类的一个原型方法(即Function.prototype里的方法),不支持ie低版本. 基本格式: function.bind(obj1,obj2,o ...
- JavaScript中的call、apply、bind方法的区别
在JavaScript 中,this的指向是动态变化的,很可能在写程序的过程中,无意中破坏掉this的指向,所以我们需要一种可以把this的含义固定的技术,于是就有了call,apply 和bind这 ...
- javascript原生bind方法ie低版本兼容详解
上一篇文章讲到了javascript原生的bind方法: http://www.cnblogs.com/liulangmao/p/3451669.html 这篇文章就在理解了原生bind方法的原理以后 ...
随机推荐
- jupyter常用快捷键
Jupyter Notebook 有两种键盘输入模式.即命令模式和编辑模式,这与 vim有些类似. 在编辑模式下,可以往单元中键入代码或文本,此时单元格被绿色的框线包围,且命令模式下的快捷键不生效. ...
- js判断background颜色明暗色调,以设置白/黑字体颜色
整理自:jscolor.js插件 this.styleElement.style.color = this.isLight() ? '#000' : '#FFF'; this.isLight ...
- 转:oracle物化视图学习笔记
最近学习了一下物化视图,正好经理不在,把学习结果贴出来供大家一起研究一下吧. 先看一下物化视图的大概含义吧,感觉baidu的定义还不错 物化视图,它是用于预先计算并保存表连接或聚集等耗时较多的操作的结 ...
- URAL - 1902 Neo-Venice
题目: Mars was the first planet colonized by humans. After a long terraforming process its appearance ...
- Django如何把数据库里的html格式输出到前端
只需在HTML页面中加入{% autoescape off %}即可! {% autoescape off %} 需要显示的数据 (% endautoescap %}
- jar包错误
Exception in thread "main" java.lang.NoSuchMethodError: org.slf4j.spi.LocationAwareLogger. ...
- Linux常用监控命令
A goal is a dream with a deadline. Much effort, much prosperity. 1.IOSTAT命令 此命令安装包为sysstat 可用yu ...
- Git服务器的Gitosis安装配置及gitignore的使用方法
Git服务器Gitosis安装设置 1.安装 openssh服务器 sudo apt-get install openssh-server openssh-client 2.创建个人公钥和私钥 在默认 ...
- ErrorHandling in asp.net web api
https://docs.microsoft.com/en-us/aspnet/web-api/overview/error-handling/exception-handling https://d ...
- TWX 比较好的多线程使用实例
using Newtonsoft.Json;using System;using System.Collections.Generic;using System.Configuration;using ...