
1. Polyfill ๐๐๐๐๐๐
// Does not work with `new funcA.bind(thisArg, args)`
if (!Function.prototype.bind) (function(){
var slice = Array.prototype.slice;
Function.prototype.bind = function() {
var thatFunc = this, thatArg = arguments[0];
var args = slice.call(arguments, 1);
if (typeof thatFunc !== 'function') {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError('Function.prototype.bind - ' +
'what is trying to be bound is not callable');
}
return function(){
var funcArgs = args.concat(slice.call(arguments))
return thatFunc.apply(thatArg, funcArgs);
};
};
})();
2. ๅ็ไบไปไน๏ผ๐ฑ๐ฑ๐ฑ๐ฑ๐ฑ๐ฑ
Does not work with new funcA.bind(thisArg, args)
3. ๅฐ้ฉฌ่ฟๆฒณ๏ผ๐ณ๐ณ๐ณ๐ณ๐ณ๐ณ
function Cat() {
console.log('this in cat is ',this)
Cat.prototype.greeting = function() {
const str = 'Hello, my name is ' + this.name
console.log(str)
}
}
const anotherCat = { name:'Jerry'}
const NewCat = Cat.bind(anotherCat)
const newCat = new NewCat()
console.log(newCat)
console.log(newCat.greeting)
่ฟ่กไปฃ็ ๏ผ่พๅบ็ปๆๅฆไธ๏ผ
this in cat is { name: 'Jerry' }
{}
undefined ? what
4. ้ฝๆฏ new ็้ ใ๐๐๐๐๐๐
- ๆ็ฝไบ new ๅ ณ้ฎๅญ็ๆบๅถๅ๏ผๆไปฌๅฐฑๅฏไปฅๅๆๅ้ข้่ฟ new ๅ ณ้ฎๅญๅฎไพๅ NewCat ็ฑป๏ผๅพๅฐ็่ฟๅๅผๆฏ็ฉบๅฏน่ฑก็ๅๅ ไบใ
- ่ฟๆฏๅ ไธบ๏ผNewCat ็ธๅฏนไบๅๅง็ Cat ๆฏไธไธชๅ จๆฐ็ๅฝๆฐ๏ผ่ฐ็จ bind ๆนๆณๆนๆณ่ฟๅ๏ผ๏ผๆไปฌๅจไฝฟ็จ new ๅ ณ้ฎๅญ่ฐ็จ NewCat ๆถ๏ผ่ฐ็จ็ๅ ถๅฎๆฏ่ฟไธชๆฐ็ๅฝๆฐ๏ผๅจๆฐๅฝๆฐไธญๅ้่ฟ call ๆนๆณ่ฐ็จ Cat ๅฝๆฐ๏ผๅนถๆฒกๆ็ดๆฅๅฏน Cat ่ฟ่กๅฎไพๅใ
- ๅจ่ฐ็จๆฐๅฝๆฐ็ๆถๅ๏ผ้ฆๅ ไผ็ๆไธไธช็ฉบๅฏน่ฑกใๆญคๅค๏ผๆฐๅฝๆฐ่ฟๆไธไธช่ฟๅๅผ๏ผ่ฟๅ็ๆฏ Cat ๅฝๆฐ่ฐ็จ็็ปๆใๅฝ Cat ไฝไธบๅฝๆฐ่้็ฑป่ฐ็จๆถ๏ผๅ ถ่ฟๅๅผๆฏ undefinedใๅ ่ๅฎไพๅ่ฟไธชๆฐๅฝๆฐ็ๆ็ป็ปๆ๏ผๅฐฑๆฏ่ฟๅๅจไฝฟ็จ new ๅฎไพๅๅฎ่ช่บซๆถๆๅๅปบ็้ฃไธช็ฉบๅฏน่ฑกใ
5. ๆ่ฏฅๆไนๅใ๐จโ๐ปโ๐จโ๐ปโ๐จโ๐ปโ๐จโ๐ปโ๐จโ๐ปโ๐จโ๐ปโ
function Cat() {
console.log('this in cat is ',this)
this.greeting = function() {
const str = 'Hello, my name is ' + this.name
console.log(str)
}
// Cat ็ this ่ขซ็ปๅฎไธบ { name:'Jerry' }๏ผ่ฟ้ๆๅจๅฐๅ
ถ่ฟๅ
return this
}
const anotherCat = { name:'Jerry'}
const NewCat = Cat.bind(anotherCat)
const newCat = new NewCat()
console.log(newCat)
่ฟ่กไปฃ็ ๏ผ่พๅบ็ปๆๅฆไธ๏ผ
this in cat is { name: 'Jerry' }
{ name: 'Jerry', greeting: [Function] }
6. ๅซ่ท้ขใ๐๐๐๐๐๐
Function.prototype.bind = function(thisObj) {
// ๅคๆญ่ฐ็จ bind ็ๆนๆณๆฏไธๆฏไธไธชๅฝๆฐ
if(typeof this !== 'function') {
throw new TypeError('ๅช่ฝๅฏนๅฝๆฐไฝฟ็จ bind ๆนๆณ')
}
// ไฟๅญๅฝๅๅฝๆฐ็ๆ้
const self = this;
// ๆฟๅฐ้ค็ฌฌไธไธชๅๆฐไปฅๅค็ๅ
ถไปๅๆฐๅ่กจ
const args = [].slice.call(arguments,1)
function Bound() {
// ๅฆๆ this instanceof Bound๏ผ่ฏดๆๆฏ้่ฟ new ๅ
ณ้ฎๅญ่ฐ็จ
// ่ฟๆถๅฐฑๅฐ this ็ดๆฅ็ปๅฎๅฐ self๏ผ่ๅฟฝ็ฅ thisObj๏ผๅจ self ๅ
้จไผๅฏน this ๆทปๅ ๅฑๆงๅๆนๆณ
return self.apply(this instanceof Bound ? this : thisObj,args.concat([].slice.apply(arguments)))
}
// ๅฎ็ฐ็ปงๆฟ
if(this.prototype){
Bound.prototype = Object.create(this.prototype)
}
return Bound
}
