基本语法
ES3 具名函数
function xxx(p1, p2) {
console.log(1)
return 2
}
匿名函数
let xxx = function (p1, p2) {
console.log(1)
return 2
}
// 首先声明一个匿名函数
function (p1, p2) {
console.log(1)
return 2
}
然后声明 let xxx
最后把匿名函数赋值给 xxx
在ES3中以上写法等价于
var xxx
temp = function (p1, p2) {
console.log(1)
return 2
}
xxx = temp
ES6中箭头函数写法
let xxx = (p1, p2) => {
console.log(1)
return 2
}
如果只有一个参数,那么可以不用写括号
let xx2 = p1 => {
console.log(1)
return 2
}
如果函数体只有一句话
let xx3 = (p1, p2) => {return p1 + p2}
那么就可以不用写括号,简写成
let xx3 = (p1, p2) => p1 + p2 // 加了花括号,那么就必须加return
// 极简化,当有一个值时
let xx4 = p1 => p1 * 2
为什么会有箭头函数
没有箭头函数的之前
function() {
// 里面有关于this的难点
}
this 是 call 的第一个参数
- 因为 this 太难用了
- JS ES3 支持 this 的
- ES6 也也支持 this, 但是箭头函数弱化了 this 的用法
ES3 怎么用 this 的
function f(p1, p2){
// var p1 = arguments[0]
// var p2 = arguments[1]
console.log(p1)
}
f('abc')
// 当只有 p1 时,p1的值是由 f(这个玩意决定的)
// 当有 p1、p2 时,p2的值是由 f(不是这个, 这个玩意决定的)
// 构造一个arguments对象,arguments = [不是这个, 这个玩意决定的]
让我们来到 this
function f(p1, p2) {
console.log(this)
}
请问 this 哪来的呢?它是什么?
let object = {
name: "obj",
hi: function(p1, p2){
console.log(this.name)
}
}
object.hi(1, 2)
// tihs 的值是谁?
从 python 的角度来看
class MyClass
"""A simple example class"""
def hi(self):
return 'hellow word'
x = MyClass()
x.hi() // hellow word
class MyClass
"""A simple example class"""
name = 'my name'
def hi(self, p1):
print self.name
print p1
x = MyClass()
x.name // my name
x.hi(1)
// my name
// 1
那么
let object = {
name: "obj",
hi: function(/* this, */p1, p2){ // JS 把this 隐藏起来了
console.log(this.name)
}
}
object.hi(/* object, */1, 2)
- p1 的值是由 object.hi(这个玩意决定的)
- p2的值是由 object.hi(不是这个, 这个玩意决定的)
- this 的值是由 这个玩意.决定的hi() object.hi(1, 2) 等价于 object.hi.call(object, 1, 2)
- 还可以说成 this 的值是由 object.hi.call(这个, 1, 2)
this 有啥问题?
var controller = {
el: '#app',
init: function(){
$(this.el).on('click', this.xxx)
},
onClick: function(){
console.log('用户点击 #app 就会调用这个函数')
// 这里的this 是什么?
this.getUsers()
// this 是你调这个函数决定的,不是你写这个函数决定的,它是调用的时候传的参数
},
getUsers: function(){
}
}
controller.init()
controller.init.call(controller) // this 是call 的第一参数
请问 this.xxx 这个函数会被调用,那它调用的时候, call 第一个参数是什么?
没有地方看调用啊=-=,jQuery 源码里有 this.xxx.call(元素),不看它调用就不知道它传的到底是个啥。在不知道调用形式的情况下无法确定形参,它们必须在调用的时候才能确定, this 也是这样的,也就是说 this 的确定方式和p1 p2 的确定方式一模一样。
那该如何知道 this.getUsers()?我又不知道,那就不用它呗
var controller = {
el: '#app',
init: function(){
var self = this // 把外面 this保留下来(坑的没有办法写的)
$(this.el).on('click', function(/* this */){ // 每个函数都有一个隐藏的this,那么这样就没有用到外面的this了
this.xxx() //这个this不是外面的,它是一个元素,每一个函数都会把this改一遍,去赋值,值为多少我不知道,它的值可不是 controller!!!
self.this() // self === controller
})
},
xxx: function(){
console.log('用户点击 #app 就会调用这个函数')
this.getUsers()
},
getUsers: function(){
}
}
controller.init()
controller.init.call(controller)
为了不要去隐藏的改这个 this 于是,就有了箭头函数
var controller = {
el: '#app',
init: function(){
$(this.el).on('click', () => { //箭头函数第一个参数就是第一个参数,它没有隐藏的 this
this.xxx() // this === controller
})
},
xxx: function(){
console.log('用户点击 #app 就会调用这个函数')
this.getUsers()
},
getUsers: function(){
}
}
controller.init()
controller.init.call(controller)
怎么证明箭头函数没有隐藏this的概念呢?
- 最外面的this是啥?fn()
- fn.call(xx)
总结
- 以前的函数永远都保留了一个潜在的参数,这个参数没有办法手动去指定,除非用 call ,JS 为了让这个参数自动的传进去,就不得不妥协,做了一个隐藏的 this 参数,python则是直接将其放在面前。
- 这段代码里的 this 是什么?
- fn()
this => window/global - obj.fn()
this => obj - fn.call(xx)
this => xx - fn.apply(xx)
this => xx - fn.bind(xx)
this => xx - new Fn()
this => 新的对象 - fn = ()=> {}
this => 外面的 this