function(输入1,输入2){
//return undefined 你不写也会返回undefined 所以经常在开发者模式下写一个函数下面会有undefined返回值
}
console.log(x)
打印什么和返回什么一点都不一样
image.png
JS的问题之一
image.png
image.png
为什么上面定义function y(){} console.log(y) 就可以,下面var x = function y(){} console.log(y) 就会报错,显示y未定义 这个说明js不一致性,下面的y只在绿色区域内有效
函数的5种声明方式
1.function f(x,y){return x+y}
2.f = function(x,y){return x+y}
3.f = function x(){}
4.f = new Function ('x','y','return x+y')
5.f = (x,y) => x+y
函数的name属性(毫无逻辑)
function f(){}
undefined
f.name
"f"//正常
var f1 = function(){}
undefined
f1.name
"f1"//正常
var f2 = function f3(){}
undefined
f2.name
"f3"//f3?what 之前不是说f3能用的地方很少。。
var f4 = new Function('x','y','return x+y')
undefined
f4.name
"anonymous"(匿名)// what?名字叫匿名。。。
var f5 = (x,y) => x+y
undefined
f5.name
"f5"// 正常
函数的本质 调用:call
函数是什么?
函数是一段可以反复调用的代码块。函数还能接受输入的参数,不同的参数会返回不同的值。
创建函数内存图
image.png
用纯对象来实现函数
var f = {} 定义一个对象
f.name ='f' 对象name属性是'f'
f.params=['x','y'] 对象的元素是'x','y'
f.functionBody = 'console.log("fff")' 对象的函数体是 'console.log("fff")'
f.call = function(){
return window.eval(f.functionBody)
} 对象的call属性通过eval执行函数体
f.call() 执行f.call f和f.call()的区别 一个是对象,一个是执行函数
什么是eval() 就是你给eval一堆字符串,他把字符串当成代码来执行
世纪难题:f(1,2) <=> f.call(undefined,1,2) 两者是等价的,但是第二个才是真正的调用
第一个是糖 第二个是硬核!!
现在f 是函数 f.call()是函数调用
this和arguments
image.png1.call 的第一个参数可以用this得到
2.call的后面的参数可以用arguments得到
在普通模式下
f=function(){console.log(this)}
ƒ (){console.log(this)}
f.call(undefined)
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
call第一个参数传入undefined会打印出window(小写,浏览器抽风会显示成大写)
image.png
在严格模式下
f1 = function(){
'use strict'
console.log(this)
}
f1.call(undefined)
VM204:3 undefined
call 传入的第一个参数是什么,this就是什么,这里this就是undeifned
image.png
综上所述,this就是call传入的第一个参数
arguments 是伪数组,怎么按断是不是一个伪数组
就是看他的- - proto - -有没有指向Array.prototype
或者说看他的原型链中有没有 Array.prototype
函数的Call Stack 调用栈
image.png 普通调用.gif 递归调用.gif 嵌套调用.gif作用域
函数当前的执行环境,作用域也可以被在层次结构中分层,以便子作用域可以访问父作用域,但反之不行。
传统错误:
function f(){
a=3
}
这里的a=3就是在声明全局变量,其实并不然
首先这只是一个赋值表达式,当前作用域没有a这个变量,会沿着树也就是作用域链寻找,一直寻找到最外层window作用域中,仍然寻找不到,此时就会退而求其次,在window作用域中先声明变量a,然后再赋值a=3,所以a就成了全局变量
经典面试题:
面试题1
var a = 1
function f1(){
alert(a) // 是多少 undefined
var a = 2
}
f1.call()
拿到代码直接做——必然会错。请先提升声明
面试题2
var a = 1
function f1(){
var a = 2
f2.call()
}
function f2(){
console.log(a) // 是多少1
}
f1.call()
拿到代码直接做——必然会错。请先提升声明
面试题3
var liTags = document.querySelectorAll('li')
for(var i = 0; i<liTags.length; i++){
liTags[i].onclick = function(){
console.log(i) // 点击第3个 li 时,打印 2 还是打印 6?6
}
}
拿到代码直接做——必然会错。请先提升声明
闭包
如果一个函数,使用了他范围外的变量,那么(这个函数+这个变量)就叫做闭包
网友评论