call/apply 都是为了改变某个函数的执行上下文而存在的,换句话说就是为了改变函数的this指向。 除了传递参数时有所差别,call和apply作用完全一样. 其中apply传递的参数为数组形式, call传递的参数为按顺序依次排列
1 2 3 4 5 6 |
// 当参数个数不确定或者你觉得用apply比较爽时, 就直接使用apply // 字面解释就是obj夺舍fn,obj拥有了执行fn函数的能力,并且this指向obj. var arguments = { 0:'name', 1:'age', 2:'gender' }; fn.apply(obj, arguments); fn.call(obj, name, age, gender); |
下面是示例代码: 1、将类数组形式转换为数组
2、方法借用
3、在继承中的应用
4、封装对象时保证this指向
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
/* * call/apply 应用实例 * 借用方法 * 若为js文件,请用node运行,若为html文件,请在浏览器中运行 */ function exam(a, b, c, d, e) { // 先看看函数的自带属性 arguments 什么是样子的 console.log(arguments); // 使用call/apply将arguments转换为数组, 返回结果为数组,arguments自身不会改变 var arg = [].slice.call(arguments); console.log(arg); } exam(2, 8, 9, 10, 3); // result: // { '0': 2, '1': 8, '2': 9, '3': 10, '4': 3 } // [ 2, 8, 9, 10, 3 ] // // 也常常使用该方法将DOM中的nodelist转换为数组 // [].slice.call( document.getElementsByTagName('li') ); |
2、方法借用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
/* * call/apply 应用实例 * 借用方法 * 若为js文件,请用node运行,若为html文件,请在浏览器中运行 */ var foo = { name: 'joker', showName: function() { console.log(this.name); } } var bar = { name: 'rose' } // bar 没有showName方法,但是可以借用foo中的showName方法实现相同的效果 foo.showName.call(bar); // 如果有参数 function _foo(name, str) { console.log('hello, ' + name + ', do you want to ' + str); } var _bar = null; _foo.apply(_bar, ['rose', 'dance']); // result // --------------------- // rose // hello, rose, do you want to dance |
3、在继承中的应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/* * call/apply 应用实例 * 实现继承 * 若为js文件,请用node运行,若为html文件,请在浏览器中运行 */ // 定义父级的构造函数 var Person = function(name, age) { this.name = name; this.age = age; this.gender = ['man', 'woman']; } // 定义子类的构造函数 var Student = function(name, age, high) { // use call Person.call(this, name, age); this.high = high; } Student.prototype.message = function() { console.log('name:'+this.name+', age:'+this.age+', high:'+this.high+', gender:'+this.gender[0]+';'); } new Student('xiaom', 12, '150cm').message(); // result // ---------- // name:xiaom, age:12, high:150cm, gender:man; |
4、封装对象时保证this指向
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
<!-- call/apply 应用实例 封装简单的jQuery插件 --> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> <title>在封装函数的过程中,确保this的正确传递</title> </head> <body> <div class="box"></div> </body> <style> .box { width: 100px; height: 100px; background: orange; } .box:hover { background: #50F573; } </style> <script> // Nicco var Nicco = function(box, str) { this.$box = box; this.str = str; } Nicco.prototype = { constructor: Nicco, params: '', // count:0, message: function() { // this.count ++; this.$box.on('mousedown', this.bindthis(this.fndown, this)); }, // 也可以直接用apply _message: function() { var _this = this; _this.$box.on('mousedown', function() { return _this.fndown.apply(_this); }) }, fndown: function() { this.params = this.str + ', uuuuuuu.';// + '-' + this.count; // this.count ++; this.$box.on('mouseup', this.bindthis(this.fnup, this)); }, fnup: function() { console.log(this.params); // this.count ++; this.$box.off(); this.$box.on('mouseup', this.bindthis(this.fnup, this)); }, // 封装一个bindthis方法,用来传递this指向,在this会被改变的地方调用 bindthis: function(fn, obj) { return function() { return fn.apply(obj, arguments); } } } // 定义jQuery插件 $.fn.mess = function(str) { var nic = new Nicco($(this), str); return nic.message(); // return nic._message(); } // 在使用中调用 $(function() { $('.box').mess('rose'); }) /*var aaa = new Nicco('jake'); aaa.message(); console.log(aaa.count);*/ </script> </html> <!-- result: rose, i love you --> |
你需要先 登录 才能发表评论.