【你不知道的javascript上】this指针,函数的call、apply、bind,new 操作符,彻底搞懂判断 this 指针的方法

预警:【你不知道的javascript】开头的文章,是用来总结书籍《你不知道的Javascript》中我不熟悉的知识,单纯的用来巩固学到的知识,和加深记忆。

可能有些地方我理解的不透彻,所以不能够保证内容的正确性,欢迎指正。

重点知识

  1. this 指向 取决于函数的【调用位置】,不像变量的作用域取决于声明的位置
  2. 默认绑定
    1. this 指向函数的调用位置,一般是全局
    2. 优先级最低的绑定
  3. 隐式绑定
    1. 用 obj.x 调用函数时,绑定给 obj(函数是做为某个对象的属性调用的)
    2. 隐式丢失: 先用 obj.xx 赋值,得到返回值后,再运行返回值,就应用了默认绑定
    3. 显示绑定
      1. 硬绑定 call / apply / bind
      2. call 接受多个参数
      3. apply 接受参数数组
      4. 怎么记住 call 和 apply 接受参数分别时啥样的呢?call单词字母少,但是参数多
      5. bind 返回一个函数
      6. 要学会手写实现 call / apply/ bind 方法,其中call  和 apply 方法类似只是参数不同
      7. // 注意这块不能使用箭头函数
        Function.prototype.myApply = function (context) {
            if (typeof this !== 'function') {
                return 
            }
            context = context || window
            context.fn = this
            let args = arguments[1] || []
            let result = context.fn(args)
            // 如果是 call 方法就应该这么写,二者只有参数不同
            // let args = [...arguments].slice(1)
            // let result = context.fn(...args)
            delete context.fn
            return result
        }
    4. new 绑定
      1. new 一个函数的时候都发生了什么
      2. new 绑定 this 指向返回的对象
    5. 优先级
      1. new > call / apply / bind> 隐式绑定  > 默认
        1. 注意 new 操作符的优先级最高,所以在我们自己实现bind的时候要注意
        2. 因为 bind 返回值是一个函数,而这个返回的函数可能被当作构造函数
        3. 所以在实现 bind 函数的时候有这个步骤
        4. Function.prototype.myBind = function(context) {
              if (typeof this !== 'function') {
                  return
              }
              context =  context || window
              let Fn = this
              let args = [...arguments].slice(1)
              return function fn() {
                  // 这一步就是因为 new 的优先级高
                  const target =  this instanceof fn ? this : context
                  return Fn.apply(target, [...arguments, ...args])
              }
          }
  4. 箭头函数的 this 指向箭头函数的声明位置
    1. 关于箭头函数,详细的请参考这篇文章

示例总结

关于 this 指针的面试题目,很多都是打印结果的,还是看几个例子吧,我还是建议看《你不知道的javascript》上,这本书里面有很多详细的介绍,还有一些关于严格模式的例子

总之记住两句话

  1. this 取决于函数的执行上下文
  2. this 的优先级 new > 显式绑定 > 隐式绑定 默认绑定

示例1

function foo() {
    console.log(this.a);
}
function doFoo() {
    foo(); 
}
var obj = {
    a: 1,
    doFoo: doFoo 
};
var a = 2;
obj.doFoo() 
doFoo()

这道题很简单,打印结果是【2,2】

知识点:隐式绑定丢失

示例2

var a = 10
var obj = {
	a: 20,
	say: () => {
		console.log(this.a)
	}
}
obj.say()

var anotherObj = { a: 30 }
obj.say.apply(anotherObj)

打印结果是【10,10】

知识点:箭头函数没有 this 指针、作用域查找

示例3

var obj = {
	say: function () {
		var f1 = () => {
			console.log(this);
		}
		f1();
	},
	pro: {
		getPro: () => {
			console.log(this);
		}
	}
}
var o = obj.say;
o(); 
obj.say(); 
obj.pro.getPro();

打印结果是【window,obj, window】

知识点:箭头函数没有 this 指针、作用域查找、隐式绑定丢失

示例4

function foo(something){
    this.a = something
}

var obj1 = {
    foo: foo
}

var obj2 = {}

obj1.foo(2); 
console.log(obj1.a); 

obj1.foo.call(obj2, 3);
console.log(obj2.a);

var bar = new obj1.foo(4)
console.log(obj1.a);
console.log(bar.a);

打印结果是【2,3,2,4】

知识点:显式绑定、new 操作符的优先级

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值