We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
回想起之前的一些面试,几乎每次都会问到一个js中关于call、apply、bind的问题,比如...
虽然网上有很多关于这方面的博客和文章,但还是决定写一篇自己对这方面知识的理解。
首先问个问题,这三个函数的存在意义是什么?答案是改变函数执行时的上下文,再具体一点就是改变函数运行时的this指向。有了这个认识,接下来我们来看一下,怎么使用这三个函数。
举个栗子
function Person(name){ this.name = name; } Person.prototype = { constructor: Person, showName: function(){ console.log(this.name); } } var person = new Person('qianlong'); person.showName();
上面的代码中person调用showName方法后会在浏览器的控制台输出qianlong
qianlong
接下来
var animal = { name: 'cat' }
上面代码中有一个对象字面量,他没有所谓的showName方法,但是我还是想用?怎么办?(坑爹了,这好像在让巧媳妇去做无米之炊),不过没关系,call、apply、bind可以帮我们干这件事。
// 1 call person.showName.call(animal); // 2 apply person.showName.apply(animal); // 3 bind person.showName.bind(animal)();
啦啦啦,有木有很神奇,控制台输出了三次cat
cat
我们拿别人的showName方法,并动态改变其上下文帮自己输出了信息,说到底就是实现了复用
上面看起来三个函数的作用差不多,干的事几乎是一样的,那为什么要存在3个家伙呢,留一个不就可以。所以其实他们干的事从本质上讲都是一样的动态的改变this上下文,但是多少还是有一些差别的..
call、apply与bind的差别
call和apply改变了函数的this上下文后便执行该函数,而bind则是返回改变了上下文后的一个函数。
call、apply的区别
他们俩之间的差别在于参数的区别,call和aplly的第一个参数都是要改变上下文的对象,而call从第二个参数开始以参数列表的形式展现,apply则是把除了改变上下文对象的参数放在一个数组里面作为它的第二个参数。
fn.call(obj, arg1, arg2, arg3...); fn.apply(obj, [arg1, arg2, arg3...]);
知道了怎么使用和他们之间的区别,接下来我们来了解一下通过call、apply、bind的常见应用场景。
var arr = [34,5,3,6,54,6,-67,5,7,6,-8,687]; Math.max.apply(Math, arr); Math.max.call(Math, 34,5,3,6,54,6,-67,5,7,6,-8,687); Math.min.apply(Math, arr); Math.min.call(Math, 34,5,3,6,54,6,-67,5,7,6,-8,687);
js中的伪数组(例如通过document.getElementsByTagName获取的元素)具有length属性,并且可以通过0、1、2...下标来访问其中的元素,但是没有Array中的push、pop等方法。我们可以利用call、apply来将其转化为真正的数组这样便可以方便地使用数组方法了。
document.getElementsByTagName
var arrayLike = { 0: 'qianlong', 1: 'ziqi', 2: 'qianduan', length: 3 }
上面就是一个普通的对象字面量,怎么把它变成一个数组呢?最简单的方法就是
var arr = Array.prototype.slice.call(arrayLike);
上面arr便是一个包含arrayLike元素的真正的数组啦( 注意数据结构必须是以数字为下标而且一定要有length属性 )
在js中要往数组中添加元素,可以直接用push方法,
var arr1 = [1,2,3]; var arr2 = [4,5,6]; [].push.apply(arr1, arr2); // arr1 [1, 2, 3, 4, 5, 6] // arr2 [4,5,6]
判断变量类型
对于对象型的数据类型,我们可以借助call来得知他的具体类型,例如数组
function isArray(obj){ return Object.prototype.toString.call(obj) == '[object Array]'; } isArray([]) // true isArray('qianlong') // false
2016.12.31日更新,有些读者对文章提了一些意见,觉得还是蛮好的,现在就其中部分进行更新。
利用call和apply做继承
var Person = function (name, age) { this.name = name; this.age = age; }; var Girl = function (name) { Person.call(this, name); }; var Boy = function (name, age) { Person.apply(this, arguments); } var g1 = new Girl ('qing'); var b1 = new Boy('qianlong', 100);
The text was updated successfully, but these errors were encountered:
No branches or pull requests
前言
作用
举个栗子
上面的代码中person调用showName方法后会在浏览器的控制台输出
qianlong
接下来
上面代码中有一个对象字面量,他没有所谓的showName方法,但是我还是想用?怎么办?(坑爹了,这好像在让巧媳妇去做无米之炊),不过没关系,call、apply、bind可以帮我们干这件事。
啦啦啦,有木有很神奇,控制台输出了三次
cat
我们拿别人的showName方法,并动态改变其上下文帮自己输出了信息,说到底就是实现了复用
区别
call、apply与bind的差别
call、apply的区别
应用
上面就是一个普通的对象字面量,怎么把它变成一个数组呢?最简单的方法就是
上面arr便是一个包含arrayLike元素的真正的数组啦( 注意数据结构必须是以数字为下标而且一定要有length属性 )
判断变量类型
2016.12.31日更新,有些读者对文章提了一些意见,觉得还是蛮好的,现在就其中部分进行更新。
利用call和apply做继承
The text was updated successfully, but these errors were encountered: