前提先掌握bind 语法和使用 ,及call ,apply的语法
1.为什么fn能调用bind方法(原型链)
obj.hasOwnProperty()
方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)。
function fn(a,b) {
console.log(this); // {x:10}
console.log(a + b);
}
let fn11 = fn.bind({x:10},1,2)
fn11()
// hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)。
console.log(fn.hasOwnProperty('bind')); // false ,fn 自身是没有bind属性的
console.log(fn.__proto__ === Function.prototype); // true ,fn的隐式原型等于构造函数Function的显示原型,显示原型上有bind, 故fn 能使用bind 方法
const object1 = {};
object1.property1 = 42;
console.log(object1.hasOwnProperty('property1'));
// expected output: true
console.log(object1.hasOwnProperty('toString')); //不是自身属性,而是Function.prototype上的方法
// expected output: false
2.手写一个bind方法
分析bind语法类似需求分析, 1.第一个参数是this, 后面可以传入多个不确定个数,2.bind 还返回一个函数
(1)我们要做的第一步 就是先取出用户传入的第一个值作为this执向, 如果取第一个值 我们想到的数组的方法最多,故我们把传入的值都存在数组当中,然后我们使用数组shift 方法取第一个值 ,shift返回被取出的值,
(2)返回一个函数 return function() {} 还需改变指向和运行 call和apply 但是接收的参数是数组 故我们使用apply()
Function.prototype.bind1 = function(...args) {
// console.log(args);
let one = args.shift()
// console.log(one);
// console.log(args);
// 这里的this 就像是写在对象里面的this 指向对象本身
let self = this
// 返回一个函数
return function() {
return self.apply(one, args)
}
}
function fn1(a,b) {
console.log(this);
console.log(a + b);
}
// fn1() //window
let a = fn1.bind1({x:1000},10, 20)
a() // {x:1000} 30
// 也可以用这种方式 将参数拆分为数组
Function.prototype.bind1 = function() {
console.log(arguments);
// 将参数拆分为数组
let args = Array.prototype.slice.call(arguments)
console.log(args);
}