call,apply,bind的理解
2020-03-19
call,apply,bind的理解
先说区别call, apply基本上没什么不一样,唯一不一样的地方是传参方式不同 但是bind和call,apply有区别。bind是重新绑定this但是不执行,而apply,call都是绑定完立即执行 举个栗子
function add(a, b) { return a + b; } function sub(a, b) { return a - b; } // apply传参是传一个数组 call是一个一个的传,这就是他们俩的区别 let result1 = add.apply(sub, [1, 2]); // 3 let result2 = add.call(sub, 1, 2); // 3 let result3 = sub.apply(add, [1, 2]); // -1 let result4 = sub.call(sub, 1, 2); // -1 // bind和apply,call不一样的是它不算立即执行,传参方式和call一样 let result5 = add.bind(sub, 1, 2)();
call,apply的理解:
1: 实际上是继承
Dog.apply(cat); 就是cat继承了Dog这个构造函数中的所有内容
function Dog(age) { this.name = 'dog'; this.showName = function () { console.log('this is a ' + this.name + age); } } function Cat(age) { this.name = 'cat'; this.showName = function () { console.log('this is a ' + this.name + age); } } let cat = new Cat(18); Dog.apply(cat, [100]); // cat继承了Dog这个构造函数中的所有内容 cat.showName(); // this is a dog100 console.log(cat.name); // dog
还可以多重继承!!!
function Sub(){ this.showSub = function(a,b){ console.log(a - b); } } function Add(){ this.showAdd = function(a,b){ console.log(a + b); } } function MathUtils(){ Sub.apply(this); Add.apply(this); // Sub.call(this); //Add.call(this); } var mathTool = new MathUtils(); mathTool.showSub(1,2); // -1 mathTool.showAdd(1,2); // 3
2: 位置很关键
调用apply,call的位置决定了最后的结果
function Dog() { this.name = 'dog'; this.showName = function () { console.log('this is a ' + this.name); } } function Cat() { // Dog.call(this); // 如果是在最开始就写Dog.call(this); // 那么下面Cat本身的this.name = 'cat'会把call继承的this.name = 'dog'覆盖;也就不会有变化 this.name = 'cat'; Dog.call(this); // Dog.call(this); 相当于在这个位置把Dog的代码复制过来 // 也就是相当于在这里写入了 // this.name = 'dog'; // this.showName = function () {...} // 显然 这里的this.name = 'dog'会把上面的this.name='cat'覆盖 this.showName = function () { console.log('this is a ' + this.name); } }