14.1 函数也是对象
匿名函数
let a = function fn(x, y){return x+y} //fn的作用域只能在等号左边生效
fn(1, 2) //Uncaught ReferenceError: fn is not defined
a(1, 2) //3
let a = function (x, y){return x+y} //a接收一个匿名函数, 和上面效果一样
返回对象:
//1. 返回简单变量
let f4 = x => x+1
//2. 返回对象
let f4 = x => ({name:x}) //用括号包裹
用构造函数新建函数:
let f= new Function('x', 'y', 'return x+y') //基本没人用, 能让人知道函数是由谁构造出来
setTimeout遇见函数的逻辑
会先把所有的语句执行完, 然后再执行setTimeout, 就好像先把这把游戏打完,再吃饭
let a=1
function fn(){
setTimeout(()=>{console.log(a)}, 0) //1. 喊你吃饭
}
fn() //输出 2
a=2 //2. 先把游戏打完
智障的 setTimeout:
//1. 把let放外面,打印是另一种结果
let i = 0
for( i=0; i<6; i++){
setTimeout(()=>{console.log(i)}, 0) // 打印6个6
}
//2. 把let 放里面结果完全不同, 把let换成var又是6个6
for(let i=0; i<6; i++){
setTimeout(()=>{console.log(i)}, 0) //打印 0 1 2 3 4 5
}
14.2 函数作用域
如何定义全局变量:
- 定义在最外边的let
- 挂载在window上的变量
什么是闭包:
14.3 参数和返回值
形参会复制变量的什么东西?
复制变量存在stack区的东西. 简单变量再stack区存的是值, 对象在stack区存的是地址. 对象将地址传行参
没写return
没写return , 会自动返回 undefined
14.4 调用栈
函数调用为啥需要用到栈?
函数里面调用其他函数, 顺序是后入先出, 所以需要用到栈
会把什么信息压入栈?
进入一个函数前, 将进入函数的具体位置压入栈, 也就是存档
为啥函数调用能写在函数定义前面?
函数永远跑到第一行
//1. 函数定义自动跑到函数调用前面
add(1, 2) //输出3
function add(x, y){
return x+y
}
//2. 函数自动跑到第一行, 会造成let定义失败
let add = 1
function add(){} //Uncaught SyntaxError: Identifier 'add' has already been declared
14.5 js第二座大山 this
每个函数都有 arguments 和this, 但箭头函数没有
arguments: 包含所有参数的伪数组
所有人不知道this, 是什么. 不给任何条件, this默认指向window
传值给this:
fn.call(xxx, 1,2,3) xxx就是传值this的参数, 后面的给arguments, 会自动转换成对象.例如1会自动转成Number(1)
解决不要自动转成对象:
function fn(){
'use strict' //求求你了js, 不要给我乱加东西
console.log(this)
}
否则: 自动转成对象, 你传undefined, js给你弄成window
this是隐藏参数, arguments是显性参数
如果没有this,会发生什么?
假如没有this:用实例名字来代替:
let person = {
name: 'frank',
sayHi(){
console.log('你好, 我叫'+ person.name) //我就用实例的名字: person
}
}
缺点:
- 如果person改名, 这个函数就挂了
- 如果实例没有创建, 只有类, 就没法这样做
如何解决?
-
传递实例: 在实例调用函数的时候, 将实例作为参数传递进去. python就用了这个方法
let person = { name: 'frank', sayHi(p){ console.log('你好, 我叫'+ p.name) //我就用实例的名字: person } } person.sayHi(person) //作为参数传递进去python的做法:
-
js走了一个更难理解的路: 用一个this表示将来会创建的, 未知实例.
具体顺序:
- 将this给人类, 人类用this定义类中的函数
- 当class实例化的时候, 把实例传递给this
14.6 要经常用call调用this
大师写法:
大师传值, 第一个参数位是this
写forEach的源代码:
Array.prototype.forEach2 = function(fn){
for(let i = 0;i<this.length;i++){
fn(this[i], i)
}
}
this的值是不确定的
this的显示和隐式传递
强行绑定this
14.7 箭头函数
箭头函数没有this!!!
如果在箭头函数中使用this, 会自动调用函数外面的this
因为对箭头函数加call, 不会改变this
14.8 立即执行函数
var想要局部变量 -> 需要一个全局函数, 在里面定义局部变量 -> 那我就定义匿名函数, 定义局部变量 -> 但是js认为我你们函数不对, -> 那我研究一些技巧骗js-> 在新版语法中很简单