實現call,apply和bind方法
阿新 • • 發佈:2020-10-25
實現call 和bind
- 改變this指向
- 傳入引數
- 返回結果
-
<script> /* 實現call() 思路: 改變this指向:可以將目標函式作為這個物件的屬性 利用arguments類陣列物件實現引數不定長 不能增加物件的屬性,所以在結尾需要delete */ Function.prototype.mycall = function (obj) { obj = obj || window; var args = []; // 引數是從1開始的
實現bind() 方法
- 改變this
- 傳入引數
- 返回函式
-
<script> /* 實現bind() bind() 方法建立一個新的函式,在 bind() 被呼叫時,這個新函式的 this 被指定為 bind() 的第一個引數, 而其餘引數將作為新函式的引數,供呼叫時使用。 說的通俗一點,bind與apply/call一樣都能改變函式this指向, 但bind並不會立即執行函式,而是返回一個綁定了this的新函式, 你需要再次呼叫此函式才能達到最終執行。 實現思路: 1. 因為bind方法不是立即執行函式,需要返回一個待執行的函式,所以使用閉包 2. 作用域繫結: 可以使用apply或call方法來實現 3. 引數傳遞: 由於引數的不確定性,需要使用apply傳遞陣列 */ // 實現簡單的bind方法 Function.prototype.mybind2 = function(obj) { var fn = this; var agrs = Array.prototype.slice.call(arguments,1); return function() { // 將回調函式的引數arguments陣列化,然後與繫結時傳入的引數args合併 var newArgs = Array.prototype.slice.call(arguments); return fn.apply(obj, args.concat(newArgs)); } } // 完整實現bind() Function.prototype.mybind2 = function(obj) { if(typeof this !== 'function') { throw new Error("Function.prototype.bind - what is trying to be bound is not callable"); }; var args = Array.prototype.slice.call(arguments,1); var fn = this; // 建立中介函式 var fn_ = function(){}; var bound = function() { var params = Arrayx.prototype.slice.call(arguments); // 通過constructor判斷呼叫方法,為true ,this指向例項,否則為obj fn.apply(this.constructor === fn ? this : obj, args.concat(params)); console.log(this); }; fn_.prototype = fn.prototype; bound.prototype = new fn_(); return bound; } // 例項 var obj = { name: "zpl", fn: function() { console.log("我的名字是" + this.name); } } var name = "zs"; obj.fn();//我的名字是zpl obj.fn.bind({name: "yz"})();//我的名字是yz var bound = obj.fn.bind({name: "ying"}); var b = new bound();//我的名字是undefined </script>
參考:
https://www.cnblogs.com/echolun/p/12178655.html
https://blog.csdn.net/qq_36367995/article/details/81319852