JS之普通函数VS箭头函数

571 阅读2分钟

箭头函数不会创建自己的this

箭头函数不会创建自己的this,所以它没有自己的this,它只会从自己的作用域链的上一层继承this。

var id = 'Global';
function fun1() {
    // setTimeout中使用普通函数
    setTimeout(function(){
        console.log(this.id);
    }, 2000);
}

function fun2() {
    // setTimeout中使用箭头函数
    setTimeout(() => {
        console.log(this.id);
    }, 2000)
}

fun1.call({id: 'Obj'});     // 'Global'
fun2.call({id: 'Obj'});     // 'Obj'

普通函数作为对象的方法调用时,this指向它所属的对象,所以 this.name就是language.name。但是,箭头函数中的this实际是继承的它定义时所处的全局执行环境中的this,所以指向Window对象,所以输出的是Window.name,Window.name是""。(这里要注意,定义对象的大括号{}是无法形成一个单独的执行环境的,它依旧是处于全局执行环境中!!)

var go = console
var language = {
	name : '',
	php(){
		var _t_ = this;
		//this是{name: "", php: ƒ, python: ƒ}
		go.info(_t_.name);
	},
	python:()=>{
		let _t_ = this;
		//this是Window{parent: Window, postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ,...}
		go.info(_t_.name);
	}
}
language.php();//运行结果:""
language.python();//运行结果:""

箭头函数继承而来的this指向永远不变

对象language的方法python是箭头函数,这个函数的this永远指向它定义时所处的全局执行环境中的this,即使这个函数是作为对象language的方法调用,this依旧指向Window对象。

.call()/.apply()/.bind()无法改变箭头函数中this的指向

.call()/.apply()/.bind()方法可以用来动态修改函数执行时this的指向,但由于箭头函数的this定义时就已经确定且永远不会改变。所以使用这些方法永远也改变不了箭头函数this的指向,虽然这么做代码不会报错。

箭头函数不能作为构造函数使用

箭头函数没有自己的arguments

箭头函数没有原型prototype

箭头函数不能用作Generator函数,不能使用yeild关键字