this的指向

this的指向

call()、apply()

call()、apply() 调用时候,修改this,只有当次调用修改,不影响函数本身this

call(obj)、apply(obj) 运行即调用

let obj1 = {
    name: 'obj1',
    fn() {
        console.log(this.name)
    }
}
let obj2 = {name: 'obj2'}
let newFn = obj1.fn
newFn.call(obj2)	// obj2
newFn.apply(obj2)	// obj2
obj1.fn()		// obj1
newFn()			// 打印为空,此时this指向window, 初始时 window.name=''
复制代码

bind()

bind(obj) 返回一个函数 需再次调用 ➡ bind(obj)()

//  接着上面代码
newFn.bind(obj2)()	// obj2
复制代码

与call()、apply()的不同

let obj1 = {
    name: 'obj1',
    fn() {
        console.log(this.name)
    }
}
let obj2 = {name: 'obj2'}
let newFn = obj1.fn.bind(obj2)
newFn()             //  obj2
newFn.call(obj1)    //  obj2
复制代码

运行一次bind()后的 newFn,是一个bound function,简称绑定函数 MDN的详细说明

  • TargetFunction:bind前的的函数
  • BoundThis:绑定的this指向
  • BoundArgs:传入的其它参数了。

当我们执行newFn时,就有点类似于TargetFunction.apply(BoundThis,BoundArgs)。

所以,当执行绑定函数时,this指向与形参在bind方法执行时已经确定了,无法改变。除非再次使用bind(obj)修改this

参数

call(this,arg1,arg2)
apply(this,[arg1,arg2])
bind(this,arg1,arg2)()

// 当this为null、undefined,this指向window
复制代码

构造器调用模式

function Dog(name, age){
    // 这里的this都是指向实例
    this.name  = name
    this.age = age
    this.sayAge = function(){
        console.log(this.age)
    }
}
var myDog = new Dog('多多', 8);
myDog.sayAge()   // 8
console.log
	myDog.__proto__.constructor 	// Dog
	myDog instanceof Dog 		// true
//   new一个函数时,同时 this 会被绑定到那个新对象上
复制代码

ES6 的箭头函数

箭头函数的 this 始终指向函数定义时的 this,而非执行时

箭头函数中没有 this 绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this,否则,this 为 undefined

var obj = {
    name : "多多",
    fn1: function () {
        console.log(this.name)
    },
    fn2: function () {
        setTimeout( () => {
            this.fn1()
        },100)
    }
}
obj.fn2()     // 多多
复制代码

使用场景

  
求数组中的最大和最小值 var arr = [1, 2, 3, 89, 46];
var max = Math.max.apply(null, arr); // 89
var min = Math.min.apply(null, arr); // 1
将类数组转为数组 var trueArr = Array.prototype.slice.call( arrayLike );
数组追加 var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
var total = [].push.apply(arr1, arr2); // 6
// arr1 = [1, 2, 3, 4, 5, 6]
// arr2 = [4, 5, 6]
判断变量类型 function isArray(obj){
return Object.prototype.toString.call(obj) == '[Object Array]';
}
// isArray([]) => true
// isArray('yw') => false
原文地址:https://www.cnblogs.com/yzy521/p/14301041.html