普通函数中this指向了调用者
function fn(){ console.log(this === window ) //true } // 通常情况下我们都会把 window 省略 fn() || window.fn() var obj = { fn1:function(){ console.log(this === obj) //true } } // obj 调用了 fn1 函数 obj.fn1()
箭头函数中的this指向了父级的上下文
var fn = ()=>{ console.log( this ===window ) // true } fn() // 就比如一个对象中的普通函数中this 指向了=>调用对象 // 普通函数返回一个对象中有一个箭头函数 其指向了父级的上下文中的this // 例: var obj = { objFn:function(){ let that = this // 保存下父级的 this 用于判断 return{ // fn2 指向一个箭头函数 fn2:()=>{ // 其父级为包裹它的作用域 console.log( this === that ) // true } } } } obj.objFn().fn2()
- 普通函数可以是(具有名字的函数)具名或匿名函数 function 声明的为具名函数 (可以new)
- 使用 let var const 声明变量接收一个函数 为匿名函数 (不能使用new创建构造函数)
- function 声明有作用域提升 (可提前使用函数)
- var 声明只不过是提升变量为一个undefined (不能提前使用函数)
- 普通函数,是有自己的原型对象的;
function Parent(name,age){ // 使用new创建一个构造函数 其this 指向了 被创建的实例 this.name = name this.age = age } // mark为被创建的实例 // mark为一个对象 身上有了 name 和 age属性 当然函数方法也可以 var mark = new Parent('Mark',20)
- 箭头函数 无法使用 new
- 且声明的函数为匿名函数
- 箭头函数,没有原型对象。
var Parent = ()=>{ } // Parent 不是一个构造函数 var mark = new Parent() // Parent is not a constructor at
- 普通函数可以使用 arguments
- 可以使用bind apply call 来改变函数内部this指向
function fn(...args){ console.log(args) // 也可以使用扩展运算符接收 ==> 一个正常的数组 console.log(arguments) // [1,2,3] ==> 伪数组 (不能使用数组的push...等方法) console.log(this.name) // mark } fn.call({name:'mark'},1,2,3)
- 箭头函数无法使用 arguments
- 且不能使用 bind apply call 改变this 的指向(可以正常传递参数)
var fn = (...args)=>{ console.log(args) // [2,3] 可以使用 console.log(arguments) // 不能使用 rguments is not defined at fn // 在fn中 arguments 没有定义 } // bind call apply 会默认把第一个参数忽略掉 fn.call(1,2,3)