简介
拿到 字节跳动实习生offer 总结
回馈分享一波自己的知识点总结
希望读者依此构建自己的知识树(思维导图)
偷懒一下:可参考我自己总结思维导图 : 点这里
附带:高频面试题积累文档。 来自于(学长、牛客网等平台)
自己开发的博客地址:zxinc520.com
github地址: 点击
此篇 js - 【this指向问题】 知识点: 全部弄懂了,面试很容易。
一、this的四条绑定规则
-
默认绑定
- 独立函数调用时,this 指向全局对象(window),如果使用严格模式,那么全局对象无法使用默认绑定, this绑定至 undefined。
-
隐式绑定
-
函数this 是指向调用者 (隐式指向)
function foo() { console.log( this.a); } var obj = { a: 2, foo: foo }; obj.foo(); // 2
- obj1.obj2.foo(); // foo 中的 this 与 obj2 绑定
-
问题:隐式丢失
- 描述:隐式丢失指的是函数中的 this 丢失绑定对象,即它会应用第 1 条的默认绑定规则,从而将 this 绑定到全局对象或者 undefined 上,取决于是否在严格模式下运行。
- 以下情况会发生隐式丢失
- 绑定至上下文对象的函数被赋值给一个新的函数,然后调用这个新的函数时
- 传入回调函数时
-
-
显式绑定
- 显式绑定的核心是 JavaScript 内置的 call(..) 和 apply(..) 方法,call 和 apply bind的this第一个参数 (显示指向)
-
new 绑定
- 构造函数的this 是new 之后的新对象 (构造器)
二、call bind apply
改变函数执行时的上下文(改变函数运行时的this指向)
2.1、apply
-
第二个参数为数组
-
自定义实现
// 自定义apply函数 Function.prototype.apply1 = function (obj, arg) { //context为null或者是undefined时,设置默认值 if (!obj) { obj = typeof window === 'undefined' ? global : window } obj.fn = this let result = null //undefined 或者 是 null 不是 Iterator 对象,不能被 ... if (arg === undefined || arg === null) { result = obj.fn(arg) } else { result = obj.fn(...arg) } delete obj.fn return result }
2.2、call
-
第二个参数为参数列表
-
自定义实现
Function.prototype.call1=function (obj,...arg) { if (!obj){ obj = typeof window ==='undefined'?global:window } obj.fn = this let result =null result=obj.fn(...arg) delete obj.fn return result }
2.3、bind
-
特点
- 返回一个函数
- 可以传入参数(使用bind时和bind新生成的函数都可以传参)
- 当 bind 返回的函数作为构造函数的时候,bind 时指定的 this 值会失效,但传入的参数依然生效
-
注意:bind这个方法在IE6~8下不兼容
-
自定义实现
Function.prototype.bind1 = function (obj,...arg) { if(!obj){ obj = typeof window === 'undefined'? global : window } let self = this let args = arg function f() {} f.prototype = this.prototype let bound = function () { let res = [...args, ...arguments] let _this = this instanceof f ? this : obj return self.apply(_this, res) } bound.prototype = new f() return bound }
2.4、区别
call和apply改变了函数的this上下文后便执行该函数,而bind则是返回改变了上下文后的一个函数。
三、相关题目
-
怎么利用call、apply来求一个数组中最大或者最小值
let arr = [1, 2, 19, 6]; Math.max.call(null, ...arr) Math.max.apply(null, arr) var fn=Math.max.bind(null,...arr) fn()
-
如何利用call、apply来做继承
-
apply、call、bind的区别和主要应用场景
- 将类数组/含有length属性的对象转化为数组
- 求数组中的最大和最小值
- 数组追加
- 利用call和apply做继承
- 判断变量类型