在Javascript中,Function是一種對象。Function對象中的this指向決定於函數被調用的方式。
這是咱們就須要用到這三個小傢伙了:call、apply、bind來改變this的指向。javascript
先來談談咱們所熟知的call和applyjava
function add(c, d){ return this.a + this.b + c + d; } var o = {a:1, b:2}; add.call(o, 3, 4); // 10 add.apply(o, [5, 6]); // 14
須要注意的是,若是傳入的第一個參數不是對象類型的,那麼這個參數會被自動轉化爲對象類型,例如:app
function age() { console.log( Object.prototype.toString.call(this) ); } bar.call(7); // [object Number]
接下來講一下bind函數
ECMAScript 5引入了Function.prototype.bind。調用f.bind(someObject)會產生一個新的函數對象。在這個新的函數對象中,this被永久綁定到了bind的第一個參數上面,不管後期這個新的函數被如何使用。this
function f(){ return this.a; } var g = f.bind({a:"jack"}); console.log(g()); // jack var o = {a:37, f:f, g:g}; console.log(o.f(), o.g()); // 37, jack function Person(name){ this.nickname = name; this.distractedGreeting = function() { setTimeout(function(){ console.log("Hello, my name is " + this.nickname); }, 500); } } var alice = new Person('Alice'); alice.distractedGreeting(); //Hello, my name is undefined function Person(name){ this.nickname = name; this.distractedGreeting = function() { setTimeout(function(){ console.log("Hello, my name is " + this.nickname); }.bind(this), 500); // <-- this line! } } var alice = new Person('Alice'); alice.distractedGreeting(); // after 500ms logs "Hello, my name is Alice" this.x = 9; var module = { x: 81, getX: function() { return this.x; } }; module.getX(); // 81 var getX = module.getX; getX(); // 9, 由於在這個例子中,"this"指向全局對象 // 建立一個'this'綁定到module的函數 var boundGetX = getX.bind(module); boundGetX(); // 81
另外,若是第一個參數爲null或者undefined的話,那麼,實際上綁定到的是全局對象,即global。這一點對三者都適用。prototype
function age() { console.log( Object.prototype.toString.call(this) ); } bar.bind()(); // [object global] bar.apply(); // [object global] bar.call(); // [object global]