this
this 指向
- 预编译过程中,
this
指向全局对象window
; - 在严格模式下
use strict
,为undefined
。 - 对象的方法里调用,
this
指向调用该方法的对象。谁调用它就指向谁 - 构造函数里的
this
,指向创建出来的实例
改变 this 指向
bind
语法
function.bind(this,args,...)
用法
// 定义一个 personA 对象
let personA = { age : 100, getAge: function(){ return this.age; } }
// 定义一个 personB 对象
let personB = { age : 10, getAge: function(){ return this.age; } }
// 调用 person 对象的方法
personA.getAge();
// 声明 personC
let personC = personA.getAge;
// 绑定不同的对象
let bindPersonA = personC.myBind(personA)
let bindPersonB = personC.myBind(personB);
console.log(bindPersonA()); // 100
console.log(bindPersonB()); // 10
手动实现一个 bind
Function.prototype.myBind = function(){
const args = Array.prototype.slice.call(arguments)
const t = args.shift()
let self = this
return function(){
return self.apply(t, args)
}
}
// 进阶版
Function.prototype.my_bind = function(ctx){
if(typeof this !== 'function'){
throw new TypeError('please bind cb function')
}
let args = Array.prototype.slice.call(arguments, 1)
let noop = function(){}
let self = this
let functionBind = function(){
return self.apply(this instanceof noop ? this: ctx, args.concat(Array.prototype.slice.call(arguments)))
}
if(this.prototype){
noop.prototype = this.prototype
}
functionBind.prototype = new noop()
return functionBind
}
call
语法
function.call(this,args,...)
用法使用
call
实现继承
// 定义父
function Parent(age){
this.age = age;
}
// 定义子
function Child(age,name){
Parent.myCall(this,age);
this.name = name
}
let child = new Child(12,'Lee')
console.log(child); // { age: 12, name: ‘Lee’ }
手动实现一个 call
Function.prototype.myCall = function(ctx, ...args){
ctx = ctx ?? window
let caller = Symbol('caller')
ctx[caller] = this
let res = ctx[caller](...args)
delete ctx.caller
return res
}
apply
语法
function.apply(this,args)
用法使用
apply
实现继承
// 定义父
function Parent(age){
this.age = age;
}
// 定义子
function Child(age,name){
Parent.myApply(this,age);
this.name = name
}
let child = new Child(12,'Joe')
console.log(child); // { age: 12, name: ‘Lee’ }
const numbers = new Array(10000).fill().map((_,index) => index +1);
// Math 工具函数
let max = Math.max.apply(null, numbers); // 10000
let min = Math.min.apply(null, numbers); // 1
let maxMy = Math.max.myApply(null, numbers); // 10000
let minMy = Math.min.myApply(null, numbers); // 1
手动实现一个 apply
// 和 call 区别只是入参不一样
Function.prototype.myApply = function(ctx, args){
// ctx or window
ctx = ctx ?? window
let caller = Symbol('caller')
ctx[caller] = this
let res = ctx[caller](...args)
delete ctx.caller
return res
}