js 中的 apply 与 call 的用法,call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向。call 和 apply 二者的作用完全一样,只是接受参数的方式不太一样。
方法定义 applyFunction.apply(obj,args) 方法能接收两个参数:
obj:这个对象将代替 Function 类里 this 对象 args:这个是数组或类数组,apply 方法把这个集合中的元素作为参数传递给被调用的函数。
callcall 方法与 apply 方法的第一个参数是一样的,只不过第二个参数是一个参数列表
在非严格模式下当我们第一个参数传递为 null 或 undefined 时,函数体内的 this 会指向默认的宿主对象,在浏览器中则是 window
- var test = function() {
- console.log(this === window);
- }
- test.apply(null); //truetest.call(undefined);//true
用法
"劫持" 别人的方法
此时 foo 中的 logName 方法将被 bar 引用 ,this 指向了 bar
- var foo = {
- name: "mingming",
- logName: function() {
- console.log(this.name);
- }
- }
- var bar = {
- name: "xiaowang"
- };
- foo.logName.call(bar); //xiaowang
实现继承
- function Animal(name) {
- this.name = name;
- this.showName = function() {
- console.log(this.name);
- }
- }
- function Cat(name) {
- Animal.call(this, name);
- }
- var cat = new Cat("Black Cat");
- cat.showName(); //Black Cat
在实际开发中,经常会遇到 this 指向被不经意改变的场景。有一个局部的 fun 方法,fun 被作为普通函数调用时,fun 内部的 this 指向了 window,但我们往往是想让它指向该 #test 节点,见如下代码:
- window.id = "window";
- document.querySelector('#test').onclick = function() {
- console.log(this.id); //test var fun = function(){ console.log(this.id); } fun();//window}
使用 call,apply 我们就可以轻松的解决这种问题了
- window.id = "window";
- document.querySelector('#test').onclick = function() {
- console.log(this.id); //test var fun = function(){ console.log(this.id); } fun.call(this);//test}
当然你也可以这样做,不过在 ECMAscript 5 的 strict 模式下,这种情况下的 this 已经被规定为不会指向全局对象,而是 undefined:
- window.id = "window";
- document.querySelector('#test').onclick = function() {
- var that = this;
- console.log(this.id); //test var fun = function(){ console.log(that.id); } fun();//test}function func(){ "use strict" alert ( this ); // 输出:undefined}func();
其他用法
类数组
这里把符合以下条件的对象称为类数组
1. 具有 length 属性
2. 按索引方式存储数据
3. 不具有数组的 push,pop 等方法
常见类数组有 arguments,NodeList!
- (function() {
- Array.prototype.push.call(arguments, 4);
- console.log(arguments); //[1, 2, 3, 4]})(1,2,3)
这样就往 arguments 中 push 一个 4 进去了
Array.prototype.push 页可以实现两个数组合并
同样 push 方法没有提供 push 一个数组, 但是它提供了 push(param1,param,…paramN) 所以同样也可以通过 apply 来装换一下这个数组, 即:
- var arr1 = new Array("1", "2", "3");
- var arr2 = new Array("4", "5", "6");
- Array.prototype.push.apply(arr1, arr2);
- console.log(arr1); //["1", "2", "3", "4", "5", "6"]
也可以这样理解, arr1 调用了 push 方法, 参数是通过 apply 将数组装换为参数列表的集合.
再比如我想求类数组中的最大值
- (function() {
- var maxNum = Math.max.apply(null, arguments);
- console.log(maxNum); //56})(34,2,56);
判断类型
- console.log(Object.prototype.toString.call(123)) //[object Number]console.log(Object.prototype.toString.call('123')) //[object String]console.log(Object.prototype.toString.call(undefined)) //[object Undefined]console.log(Object.prototype.toString.call(true)) //[object Boolean]console.log(Object.prototype.toString.call({})) //[object Object]console.log(Object.prototype.toString.call([])) //[object Array]console.log(Object.prototype.toString.call(function(){})) //[object Function]
就爱阅读 www.92to.com 网友整理上传, 为您提供最全的知识大全, 期待您的分享,转载请注明出处。
来源: http://www.92to.com/bangong/2017/04-07/20090901.html