call

经常使用的场景,函数形参数组化,然后使用数组的一些方法
Array.property.slice.call(arguments)

  1. function person() {
  2. console.log(this.name)
  3. }
  4. var egg = {
  5. name: "笑"
  6. }
  7. person.call(egg) // 笑

对于调用者person来说,call改变了this指向,this指向call的第一个参数: egg
对于egg来说,相当于是增加了person方法
即:

  1. var egg = {
  2. name: '笑',
  3. person: function() {
  4. console.log(this.name)
  5. }
  6. }
  7. egg.person()

image.png

  1. function person() {
  2. console.log(this.name)
  3. }
  4. var egg = {
  5. name: "笑"
  6. }
  7. Function.prototype.newCall = function(obj){
  8. console.log(this)
  9. };
  10. person.newCall(egg) // 输出person函数,因为person是调用者, this指向person

call()
call的第一个参数就是this指向

call除了第一个参数之外还可以接收多个参数
apply除了第一个参数之外只能就收一个参数数组

bind

bind会返回一个永久改变this指向的函数,不会立即执行,需要手动调用
bind().bind()链式调用的时候,this绑定第一个bind传入的对象

  1. const name="lucy";
  2. const obj={
  3. name:"martin",
  4. say:function () {
  5. console.log(this.name);
  6. }
  7. };
  8. obj.say(); //martin,this指向obj对象
  9. setTimeout(obj.say,0); //lucy,this指向window对象
  10. // bind
  11. const name="lucy";
  12. const obj={
  13. name:"martin",
  14. say:function () {
  15. console.log(this.name);
  16. }
  17. };
  18. const obj2={name:"xixixixi"}
  19. obj.say(); //martin,this指向obj对象
  20. setTimeout(obj.say.bind(obj).bind(obj2),0); //martin,this指向obj对象
  21. const name="lucy";
  22. const obj={
  23. name:"martin",
  24. say:function () {
  25. console.log(this.name);
  26. }
  27. };
  28. const obj2={name:"xixixixi"}
  29. obj.say(); //martin,this指向obj对象
  30. setTimeout(obj.say.bind(obj2).bind(obj),0); //xixixixi,this指向obj2对象
  31. obj.say.bind(obj).bind(obj2)()
  32. // martin
  33. obj.say.bind(obj2).bind(obj)()
  34. // xixixixi