一、JavaScript
1、立即执行函数
demo:
输出2 1
function test1() {
console.log(1)
}
function test2() {
console.log(2)
}
test2()
function test3() {
test1()
}
test3()
说明,写到全局的函数,都是保留在GO(全局执行期上下文)里面的,不释放的。
在哪个地方调用这个函数,都可以直接调用。 (始终都在GO)
demo2:
下面函数只执行一次
add(1, 2)//3
function add(a, b) {
console.log(a + b)
}
1.不需要手动的执行,自动执行
2.立即执行函数 --功能性称呼叫初始化函数
**英文缩写:**IIFE(immediately-invoked function expression)立即执行的函数表达
**立即执行函数两个特点:**1.加载的时候自动执行 2 .页面执行完成之后立即销毁
两种写法:
写法一:
(function(){
//内容
})()
写法二:
(function(){
}())//w3c建议 这上面那种也蛮多的
例子:
console.log(add(1, 2))//3
function add(a, b) {
return a + b
}
(function () {
var a = 1
var b = 2
console.log(a + b)//3
})()
3.不写匿名函数,写一个声明函数。
(function test() {
var a = 1
var b = 2
console.log(a + b)//3
// return a + b
})()
但是test函数找不到
引用错误,test写它或者不写它,结果是一样的,证明函数执行完成之后,函数被销毁了
参数
小括号代表是执行函数,所以可以放入形参
(function (a, b) {
console.log(a + b)//3
// return a + b
})(1, 2)
上面满足了,页面加载完成之后呢,执行js的时候,1.这个函数自己就执行了,2.执行完之后被释放
还没满足:拿到函数执行出来的值(未完成)
想要拿到a+b的值就要return出去,
返回值问题
var num = (function (a, b) {
// console.log(a + b)
return a + b
})(3, 2)
console.log(num)//5
也就是说,立即执行函数也是有返回值的,你要接受它的返回值,就要把它交给一个变量,来保存
函数用()括起来,就是表达式。
思考:这样能执行吗?
function test(){
}();//报错(语法错误)
这样能执行吗?
var test =function(){ // 把匿名函数赋值给test
console.log(1);//1 可以执行
}();
总结:一定是表达式,才能执行符号执行
你括号里面包裹不管是什么东西,都会变成表达式
注意:
var test1 =function(){
console.log(2);
}();
console.log(test1)//undefined
小野森森说被销毁了,弹幕说:
这里是因为这里不是函数被销毁了,是因为函数没有返回值,默认返回undefined
函数前面有符号,也能立即实行
就是让一个函数,函数声明变成一个表达式的方法,
//+ - ! && ||
+ function test(){
console.log(1);
}()//1
2 && function test(){//与运算前面写真的
console.log(1);
}()
undefined || function test(){
console.log(1)
}()
**总结:**将函数声明转化为表达式后,就可以使用执行符号了,立即执行该函数,并且该函数声明的函数名自动就被忽略掉了。
**面试题:**是否报错
function test(a){
}(6)//6
不报错.
分析:js引擎,看到里面传值了,它就优先把它解析成一个表达式。如果()不传值的话,就报错
2、逗号运算符
返回逗号后面的值
function test(a,b){
console.log(1)
}(6,5)//5
var num =(2-1,6+5)
console.log(num)//11
function test(){}
var num =(6);
console.log(num)
3、笔试题
function test() {
var arr = []
for (var i = 0; i < 10; i++) {
arr[i] = function () {
document.write(i + ' ')
}
}
return arr
}
var myArr = test()
console.log(myArr)//10个function
打印出arr相对应下标的函数
function test() {
var arr = []
for (var i = 0; i < 10; i++) {
arr[i] = function () {
document.write(i + ' ')
}
}
return arr
}
var myArr = test()
for (var j = 0; j < 10; j++) {
myArr[j]()//10个10
}
为什么是10个10
解释:
i走到10的时候,停止,把arr
return出去的时候,形成了10个闭包,因为arr里面存了10个匿名函数,将这10个匿名函数return出去,
所以在下面循环myArr[j]
的时候,拿到的值,实际上是最后一次i的值
function test() {
var arr = []
var i = 0//i变成10的时候,不小于10,所以停止
for (; i < 10; ) {
arr[i] = function () {
document.write(i + ' ')
}
i++
}
return arr
}
var myArr = test()
for (var j = 0; j < 10; j++) {
myArr[j]()//10个10
}
可以理解为,i开辟了内存并并赋值,最终为10,虽有的打印其实都这个内存空间的,所以都是10
闭包复习
跟上面的案例一样
function test(){
var num =10;
var a =function(){
console.log(n);
}
var b =function(){
console.log(n)
}
return [a,b]
}
var arr =test()
arr[0]()//10
arr[1]()//10
思考:如果想打印0~9的话,该怎么打印
方法一:让函数立即执行
在循环的时候,就立即执行了,这样的话函数立即执行,每一次拿到的i都不一样
function test() {
var arr = []
for (var i = 0; i < 10; i++) {
arr[i] = (function () {
console.log(i + ' ')
})()
}
}
test()
或者传参(方法二)
function test() {
var arr = []
for (var i = 0; i < 10; i++) {
arr[i] = function (num) {//传参
console.log(num + ' ')
}
}
return arr
}
var myArr = test()
for (var j = 0; j < 10; j++) {
myArr[j](j)//传参
}
思考:每一次循环的时候,都能把i
保存到立即执行函数里面去
方法三:最常用方法:
function test() {
var arr = []
for (var i = 0; i < 10; i++) {
;(function (num) {
arr[num] = function () {
console.log(num + ' ')
}
})(i)
}
return arr
}
var myArr = test()
for (var j = 0; j < 10; j++) {
myArr[j]()
}
二、面试题
1、书籍推荐
前端:
-
《JavaScript高级程序设计》
-
《你不知道的JavaScript》 上中下
计算机原理:
-
编码:隐藏在计算机软硬件背后的语言
-
算法图解
-
图解http
-
大话数据结构
2、从URL输入页面到展现到底发生了什么?
-
DNS解析:把域名解析成ip地址
-
建立TCP链接:TCP三次握手
-
发送HTTP请求
-
服务器处理请求并返回HTTP报文
-
浏览器解析渲染页面
-
断开连接:TCP四次挥手