call/apply
能夠改變函數的this
指向。 除了傳遞參數時有所差異,call
和apply
做用徹底同樣。node
var tim = { name: 'tim', age: 20, getName: function() { console.log(this.name); return this.name; } } var jake = { name: 'jake', age: 20 } tim.getName(); // tim // jake對象沒有getName方法,可是能夠經過call/apply去使用tim對象的getName方法 tim.getName.call(jake); // jake tim.getName.apply(jake); // jake
tim.getName.call(jake)
的意思是執行getName
方法,可是經過call/apply
將getName
方法中的this
指向強行設置爲jake
對象。所以最終的返回結果會是jake。數組
call apply
的不一樣之處在於傳遞參數的形式。其中apply
傳遞的參數爲數組形式, call
傳遞的參數爲按順序依次排列。一個簡單的實例說明。app
// 當參數個數不肯定或者你以爲用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);
下面我收集了幾個我遇到過的實際例子函數
// arguments // 返回值爲數組,arguments保持不變 var arg = [].slice.call(arguments); // nodeList var nList = [].slice.call(document.getElementsByTagName('li'));
var foo = { name: 'joker', showName: function() { console.log(this.name); } }; var bar = { name: 'rose' }; foo.showName.call(bar); // rose
// parent var Person = function(name) { this.name = name; this.gender = ['man', 'woman']; } // child var Student = function(name, age) { // inherit Person.call(this); } Student.prototype.message = function() { console.log('name:'+this.name+', age:'+this.age+', gender:.'+this.gender[0]); } var xm = new Student('xiaom', 12); xm.message(); //name:undefined, age:undefined, gender:.man
var Nicco = function(name) { this.name = name; } Nicco.prototype = function() { constructor: Nicco, message: function() { var _this = this; addEventListener( 'mousedown', function() { // stay this return _this.fndown.call(_this); }, false ); }, fndown: function() { var _this = this, str = this.name + ', i miss you.'; addEventListener( 'mouseup', function() { return _this.fnup.call(_this, str); }, false ); }, fnup: function(str) { console.log(str); } }