作者:小白君
转载请标明出处
1. this的默认行为-默认绑定规则
独立函数调用时,应用默认绑定规则。可以看作无法应用其他规则时的默认规则
默认绑定规则,在非严格模式先指向
window, 严格模式下指向undefined
function foo() {
console.log(this.a)
}
// 这里不能用let或者const的原因是, var声明的变量会作为window的属性, let和const声明的变量并不会
var a = 2
foo() // 2
2. this的悄悄行为-隐式绑定
当函数调用时有上下文对象时,隐式绑定规则会把函数调用中的
this绑定到这个上下文对象上
function foo() {
console.log(this.a)
}
let obj2 = {
a: 42,
foo: foo
}
let obj1 = {
a: 2,
obj2: obj2
}
// 对象属性引用链中只有上一层或者说最后一层在调用位置中起作用
obj1.obj2.foo() // 42
隐式丢失(对函数的引用调用, 传入回调函数时)
function foo() {
console.log(this.a)
}
function doFoo(fn) {
fn()
}
var obj = {
a: 2,
foo: foo
}
var a = 'oops, global'
doFoo(obj.foo) // oops, global
3. this的明面上的行为-显示绑定
通过
call(..),apply(..),bind(..)将this显示的绑定到摸个对象上
function foo() {
console.log(this.a)
}
var obj = {
a: 2
}
foo.call(obj) // 2
4. this的new绑定行为
使用
new调用函数时,会自动执行下面的操作
- 创建一个新的对象
- 这个新对象会被执行原型链连接
- 函数调用时的
this绑定到这个对象上
- 如果函数没有返回其它对象,则自动返回这个对象
5. this绑定优先级
new绑定 > 显示绑定 > 隐式绑定 > 默认绑定
6. 箭头函数this绑定规则
在箭头函数内部,
this绑定不是动态的, 而是词法的, 简言之箭头函数的this指向的是函数定义时的上下文对象,而不是调用时的上下文对象
箭头函数没有自己的
arguments, 而是继承自父层
7. call, apply, bind实现
1. call实现
Function.prototype.callFn = function(context, ...args) {
if (typeof this !== 'function') {
throw new TypeError(this + ' is not a function')
}
if (typeof context === 'undefined' || context === null) {
context = window
}
let fnSymbol = Symbol()
context[fnSymbol] = this
let result = context[fnSymbol](...args)
delete context[fnSymbol]
return result
}
2. apply实现
Function.prototype.applyFn = function(context, args) {
if (typeof this !== 'function') {
throw new TypeError(this + ' is not a function')
}
if (typeof context === 'undefined' || context === null) {
context = window
}
let fnSymbol = Symbol()
context[fnSymbol] = this
let result = context[fnSymbol](...args)
delete context[fnSymbol]
return result
}
3. bind实现
Function.prototype.bindFn = function(context, ...thisArgs) {
if (typeof this !== 'function') {
throw new TypeError(this + ' is not a function')
}
if (typeof context === 'undefined' || context === null) {
context = window
}
let self = this
return function(...args) {
return self.apply(context, args.concat(thisArgs))
}
}
4. new 的实现
function newFn() {
let newObj = {}
Constructor = [].shift.call(arguments)
newObj.__proto__ = Constructor.prototype
const result = Constructor.apply(newObj, arguments)
return typeof result === 'object' ? result : newObj
}