今天來聊聊bind 關於以前的call跟apply 查看此連接segmentfault
咱們要明確4點內容app
1. bind以後返回一個函數函數
let obj = { name : 'skr' } function fn(){ console.log(this) } let bindfn = fn.bind(obj) console.log(typeof bindfn) // function
2.bind改變this 而且能夠傳參 bind以後的函數仍舊能夠傳參this
let obj = { name : 'skr' } function fn(){ console.log(arguments,this) } let bindfn = fn.bind(obj,'陳','孫','李') bindfn('張三李四') //[Arguments] { '0': '陳', '1': '孫', '2': '李', '3': '張三李四' },{ name: 'skr' }
3.bind以後的函數作爲構造函數執行,this是做爲新的一個引用prototype
let obj = { name : 'skr' } function fn(name){ this.name = name console.log(this) //{ name: '坤坤' } console.log(obj) //{ name: 'skr' } } let bindfn = fn.bind(obj) let obj2 = new bindfn('坤坤')
4 做爲構造函數時候 在原型上添加屬性 實例能找到這個屬性code
let obj = { name : 'skr' } function fn(name){ this.name = name console.log(this) //{ name: '坤坤' } console.log(obj) //{ name: 'skr' } } let bindfn = fn.bind(obj) let obj2 = new bindfn('坤坤') fn.prototype.arrt = '小生' console.log(obj2.arrt) // 小生
遵循以上4點get
Function.prototype.bind = function(){ return function(){ // 代碼省略 } }
Function.prototype.bind = function(context){ let _this = this let args = Array.prototype.slice.call(arguments,1) // 保存外部函數的參數 return function(){ return _this.apply(context,args.concat(Array.from(arguments))) // 連接內部函數參數 } } let obj = { name :"1" } function a(){ console.log(this,arguments) } a.bind(obj,1,2,3,4,5,6)(7,8,9) /* 打印結果: { name: '1' } [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5, '5': 6, '6': 7, '7': 8, '8': 9 } */
Function.prototype.bind = function(context){ let _this = this let args = Array.prototype.slice.call(arguments,1) // 保存外部函數的參數 let fn2 = function(){ return _this.apply(this instanceof fn2 ? this:context ,args.concat(Array.from(arguments))) // 看看是不是new 出來的 是new的話就不改變this } return fn2 } let obj = { name :"1" } function a(name){ this.name = name console.log(this) } let bindfn = a.bind(obj) let obj2 = new bindfn('2') // {name:'2'} console.log(obj) // {name:'1'}
Function.prototype.bind = function(context){ let _this = this let args = Array.prototype.slice.call(arguments,1) // 保存外部函數的參數 function ConS(){} let fn2 = function(){ return _this.apply(this instanceof fn2 ? this:context ,args.concat(Array.from(arguments))) // 看看是不是new 出來的 是new的話就不改變this } console.log(this) ConS.prototype = this.prototype // 經過第三方 new ConS().__proto__ === this.prototype fn2.prototype = new ConS() // new fn2().__proto__ === new ConS() ---> new fn2().__proto__.__proto__ === this.prototype 從而拿到this實例上的原型屬性和方法 return fn2 } let obj = { name :"1" } function a(name){ this.name = name console.log(this) } let bindfn = a.bind(obj) let obj2 = new bindfn('2') // {name:'2'} console.log(obj2) // {name:'1'}
大體上就是這樣了原型