1.函数声明
function f(){}
函数声明优先级大于变量提升
function a(){
return b;
b=10;
function b(){}
var b="11"
}
console.log(typeof a())
答案:function
解析:考察[函数提升]优先级>[变量提升]
return后面的不执行
function a(){
function b(){}
return b;
b=10;
var b="11"
}
2.函数表达式
创建了一个匿名函数,没有函数提升,但得注意变量提升
var f = function (){}
注意:函数表达式定义的函数,函数名外部无法引用,如下:
1. var fn = function f(){};
console.log(typeof f); //打印undefined,函数表达式的函数名f在外部是访问不到的
2. if(function f(){}){
console.log(typeof f); //同理,打印undefined,if语句中的函数解析为函数表达式,函数名f在外部是访问不到的
}
作者:zh2443
链接:https://www.jianshu.com/p/5304f4196d2c
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
3.构造函数
function Person( name){
this.name =name;
}
var Fsskay=new Person('Fss');
console.log(Fsskay.name) //Fss
构造函数的this指向window
函数内部可以读取外部变量(作用域链由内往外)[例子f3],外部不能读取函数内的局部变量[例子f1]
函数内部声明var会变量提升[例子f1],函数内部的函数声明会函数提升
函数内部声明变量不用var,会修改外部变量[例子f3]
var v = 1;
function f1(){
console.log(v,'v1')//undefined,因为内部变量提升var a
var v = 2;
console.log(v,'v2');//2
}
console.log(v)//1
function f2(){
console.log(v,'v3') //1 读取的全局变量
}
分割线------------------------------------------------------------------
function f3(){
v=3
};
f3() //执行下f3
console.log(v,'全局的那个v')//3
函数本身也是一个值,也有自己的作用域。它的作用域与变量一样,就是其声明时所在的作用域,与其运行时所在的作用域无关。
例子
var a = 1;
var x = function () {
console.log(a);
};
function f() {
var a = 2;
x();
}
f() // 1
考题:
var a =3;
var b={
a:2,
b:{
a:1,
c:function(){
return this.a
}
}
}
var test = b.b.c;
console.log(test())
console.log(b.b.c())
答案://3
//1
解析:考察浅拷贝与this的指向,考察 函数作用域是在声明时候的作用域
test=b.b.c ,test=f(){ return this.a},test()所在的作用域是全局window,window下的a=3,所以第一个是3
b.b.c()的this就是c所在的对象b下的a,所以this.a是a=1
什么是闭包? 让外部读取函数内部变量
怎么做? 函数1内再给一个函数2,返回这个函数2的结果
function f1(){
var n=1
function f2(){
console.log(n)
}
return f2()
}
// 1
有什么用?
1.外部函数访问内部函数作用域,减少使用全局变量
2.内部变量不垃圾回收,占内存
是什么?函数创建后立即执行,本质上是函数表达式(具名或匿名的)
怎么做?
(function(){})
(function(){})();
!function(){}();
+function(){}();
-function(){}();
~function(){}();
有什么用?
1.封装私有变量,外部读取不到内部函数
2.一种函数的调用方式,调用后垃圾回收,不占内存
3.只有表达式才能被执行,只执行一遍就自动销毁
简单来说就是自己调用自己,递归需要设置结束条件
function f(n){
if(n === 1){
return 1
}
return n * f(n-1)
}
f(3) //6
细看可以看https://www.cnblogs.com/humin/p/4556820.html
大概记一下就是原型链继承prototype,构造函数继承,ES6 extends继承.
fn.call(this,参数列表) 立即调用
fn.apply(this.参数数组) 立即调用
fn.bind(this,参数列表) 之后调用
bind 方法返回值是函数以及 bind 接收的参数列表的使用。
bind 方法不会立即执行,而是返回一个改变了上下文 this 后的函数。
参数的使用
function fn(a, b, c){
console.log(a, b, c);
}
var fn1 = fn.bind(null, '123');
fn('A', 'B', 'C'); // A B C
fn1('A', 'B', 'C'); // 123 A B
fn1('B', 'C'); // 123 B C
fn.call(null, '123'); // 123 undefined undefined call 是把第二个及以后的参数作为 fn 方法的实参传进去,而 fn1 方法的实参则是在 bind 中参数中的基础上再往后排