服务外包网站西安高端网站设计公司
web/
2025/9/30 17:00:42/
文章来源:
服务外包网站,西安高端网站设计公司,深圳网站关键词优化公司哪家好,网站开发合同是否专属管辖1.call/apply/bind方法的来源 首先#xff0c;在使用call#xff0c;apply#xff0c;bind方法时#xff0c;我们有必要知道这三个方法究竟是来自哪里#xff1f;为什么可以使用的到这三个方法#xff1f; call#xff0c;apply#xff0c;bind这三个方法其实都是继承自…1.call/apply/bind方法的来源 首先在使用callapplybind方法时我们有必要知道这三个方法究竟是来自哪里为什么可以使用的到这三个方法 callapplybind这三个方法其实都是继承自Function.prototype中的属于实例方法。 1 console.log(Function.prototype.hasOwnProperty(call)) //true
2 console.log(Function.prototype.hasOwnProperty(apply)) //true
3 console.log(Function.prototype.hasOwnProperty(bind)) //true 上面代码中都返回了true表明三种方法都是继承自Function.prototype的。当然普通的对象函数数组都继承了Function.prototype对象中的三个方法所以这三个方法都可以在对象数组函数中使用。 关于继承的概念会在以后与大家分享。 2.Function.prototype.call() 函数实例的call方法可以指定该函数内部this的指向即函数执行时所在的作用域然后在所指定的作用域中调用该函数。并且会立即执行该函数。 看个例子来好好理解这段话。 1 var keith {2 rascal: 1233 };4 5 var rascal 456;6 7 function a() {8 console.log(this.rascal);9 }
10
11 a(); //456
12 a.call(); //456
13 a.call(null); //456
14 a.call(undefined); //456
15 a.call(this); //456
16 a.call(keith); //123 上面代码中a函数中的this关键字如果指向全局对象返回结果为456。可以看到如果call方法没有参数或者参数为null或undefined或者this则等同于指向全局对象。如果使用call方法将this关键字指向keith对象也就是将该函数执行时所在的作用域为keith对象返回结果为123。 call()方法可以传递两个参数。第一个参数是指定函数内部中this的指向也就是函数执行时所在的作用域第二个参数是函数调用时需要传递的参数。 1 function keith(a, b) {
2 console.log(a b);
3 }
4
5 keith.call(null, 1, 2); //3 第一个参数是必须的可以是nullundefinedthis但是不能为空。设置为nullundefinedthis表明函数keith此时处于全局作用域。第二个参数中必须一个个添加。而在apply中必须以数组的形式添加。 call方法的一个应用是调用对象的原生方法。也可以用于将类数组对象转换为数组。 1 var obj {};2 console.log(obj.hasOwnProperty(toString)); //false3 4 obj.hasOwnProperty function() {5 return true;6 }7 8 console.log(obj.hasOwnProperty(toString)); //true9
10 console.log(Object.prototype.hasOwnProperty.call(obj, toString)); //false 上面代码中hasOwnProperty是obj对象继承的方法如果这个方法一旦被覆盖就不会得到正确结果。call方法可以解决这个方法它将hasOwnProperty方法的原始定义放到obj对象上执行这样无论obj上有没有同名方法都不会影响结果。要注意的是hasOwnProperty是Object.prototype原生对象的方法而call是继承自Function.prototype的方法。 3.Function.prototype.apply() apply方法的作用与call方法类似也是改变this指向函数执行时所在的作用域然后在指定的作用域中调用该函数。同时也会立即执行该函数。唯一的区别就是它接收一个数组作为函数执行时的参数。 apply方法的第一个参数也是this所要指向的那个对象如果设为null或undefined或者this则等同于指定全局对象。第二个参数则是一个数组该数组的所有成员依次作为参数在调用时传入原函数。原函数的参数在call方法中必须一个个添加但是在apply方法中必须以数组形式添加。 看一下callapply的细微差别。 1 function keith(a, b) {
2 console.log(a b);
3 }
4
5 keith.call(null, 2, 3); //5
6 keith.apply(null, [2, 3]); //5 上面代码中第一个参数为null指向全局作用域第二个参数传入的形式稍稍不同。 apply方法有以下应用。 3.1找出数组中的最大数 1 var a [2, 4, 5, 7, 8, 10];
2
3 console.log(Math.max.apply(null, a)); //10
4 console.log(Math.max.call(null,2, 4, 5, 7, 8, 10)); //10 Javascript中是没有提供找出数组中最大值的方法的结合使用继承自Function.prototype的apply和Math.max方法就可以返回数组的最大值。 3.2将数组的空元素变为undefined 通过apply方法利用Array构造函数将数组的空元素变成undefined。 1 console.log(Array.apply(null, [1, , 3])); // [1, undefined, 3] 空元素与undefined的差别在于数组的forEach方法会跳过空元素但是不会跳过undefined和null。因此遍历内部元素的时候会得到不同的结果。 var a [1, , 3];a.forEach(function(index) {console.log(index); //1,3 跳过了空元素。})Array.apply(null,a).forEach(function(index){console.log(index); 1,undefined,3 将空元素设置为undefined}) 3.3转换类似数组的对象 另外利用数组对象的slice方法可以将一个类似数组的对象比如arguments对象转为真正的数组。当然slice方法的一个重要应用就是将类似数组的对象转为真正的数组。call和apply都可以实现该应用。 1 console.log(Array.prototype.slice.apply({0:1,length:1})); //[1]
2 console.log(Array.prototype.slice.call({0:1,length:1})); //[1]
3 console.log(Array.prototype.slice.apply({0:1,length:2})); //[1,undefined]
4 console.log(Array.prototype.slice.call({0:1,length:2})); //[1,undefined] 1 function keith(a,b,c){
2 return arguments;
3 }
4
5 console.log(Array.prototype.slice.call(keith(2,3,4))); //[2,3,4] 上面代码的callapply方法的参数都是对象但是返回结果都是数组这就起到了将对象转成数组的目的。从上面代码可以看到这个方法起作用的前提是被处理的对象必须有length属性以及相对应的数字键。 4.Function.prototype.bind() bind方法用于指定函数内部的this指向执行时所在的作用域然后返回一个新函数。bind方法并非立即执行一个函数。 1 var keith {2 a: 1,3 count: function() {4 console.log(this.a);5 }6 };7 8 keith.count(); //19 keith.count(); //2
10 keith.count(); //3 上面代码中如果this.a指向keith对象内部的a属性如果这个方法赋值给另外一个变量调用时就会出错。 1 var keith {
2 a: 1,
3 count: function() {
4 console.log(this.a);
5 }
6 };
7
8 var f keith.count;
9 f(); //NaN 上面代码中如果把count方法赋值给f变量那么this对象指向不再是keith对象了而是window对象。而window.a默认为undefined进行递增运算之后undefined就等于NaN。 为了解决这个问题可以使用bind方法将keith对象里的this绑定到keith对象上或者是直接调用。 1 var f keith.count.bind(keith);
2 f(); //1
3 f(); //2
4 f(); //3 1 keith.count.bind(keith)() //1
2 keith.count.bind(keith)() //2
3 keith.count.bind(keith)() //3 当然this也可以绑定到其他对象上。 1 var obj {
2 a: 100
3 };
4 var f keith.count.bind(obj);
5 f(); //100
6 f(); //101
7 f(); //102 同样我们也可以给bind方法传递参数第一个参数如果为null或者undefined或者this会将函数内部的this对象指向全局环境第二个为调用时需要的参数并且传递参数的形式与call方法相同。 1 function keith(a, b) {
2 return a b;
3 }
4 console.log(keith.apply(null,[1,4])); //5
5 console.log(keith.call(null,1,4)); //5
6 console.log(keith.bind(null, 1, 4)); //keith()
7 console.log(keith.bind(null, 1, 4)()); //5 上面代码中可以看出callapplybind三者的区别call和apply方法都是在调用之后立即执行的。而bind调用之后是返回原函数需要再调用一次才行有点像闭包的味道如果对闭包概念不熟悉可以浏览这两篇文章javascript--函数参数与闭包--详解javascript中重要概念-闭包-深入理解。 5.绑定回调函数的对象 在这篇文章javascript之 this 关键字详解中有谈及到如果在回掉函数中使用this对象那么this对象是会指向DOM对象也就是button对象。如果要解决回调函数中this指向问题可以用如下方法。 1 var o {2 f: function() {3 console.log(this o);4 }5 }6 7 $(#button).on(click, function() {8 o.f.apply(o);9 //或者 o.f.call(o);
10 //或者 o.f.bind(o)();
11 }); 点击按钮以后控制台将会显示true。由于apply方法或者call方法不仅绑定函数执行时所在的对象还会立即执行函数而bind方法不会立即执行注意区别因此不得不把绑定语句写在一个函数体内。 6.callapplybind方法的联系和区别 其实用于指定函数内部的this指向的问题这三个方法都差不多只是存在形式上的差别。读者可以将以上的例子用三种方法尝试用三种方法实现。 总结一下callapplybind方法 a第一个参数都是指定函数内部中this的指向函数执行时所在的作用域然后根据指定的作用域调用该函数。 b都可以在函数调用时传递参数。callbind方法需要直接传入而apply方法需要以数组的形式传入。 ccallapply方法是在调用之后立即执行函数而bind方法没有立即执行需要将函数再执行一遍。有点闭包的味道。 d改变this对象的指向问题不仅有callapplybind方法也可以使用that变量来固定this的指向。转载于:https://www.cnblogs.com/Jade-Liu18831/p/9580410.html
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/84552.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!