函数

函数是一个对象。typeof 检查时,返回function

  1. 构造函数创建函数对象。封装的代码以字符串的形式传递给构造函数。但不是非要加“”

var func = new Function("console.log('构造函数');"); 这个构造方式可以使用console.log(func)输出该方法的内容。function fun(){}则不能console.log输出方法内容。

  1. 封装到函数中的代码不会立即执行,指挥在调用的时候执行。
  2. 常用的函数声明: 一: function fun(){} 二:var fun = function(){}

函数的参数

  1. 调用函数时解析器不会检查实参的类型。

    注意,是否可能会接收到非法参数,若有,则对参数进行数据类型检查

    函数的实参可以是任意的数据类型

  2. 调用函数时,解析器也不会检查实参的数量。

    多余实参不会被赋值

    如果实参的数量少于形参的数量。没有对应实参的形参 时 undefined

  3. 实参可以是一个对象,也可以是一个函数。

返回值

  1. return语句后的都不执行。
  2. return;====>没有返回值,相当于返回 undefined
  3. 函数没有return,也相当于返回undefined
  4. return后可以跟任意类型的值

    fun(miao()); //函数返回值
    fun(miao); //调用函数对象
    /*
    miao()
    1.调用函数
    2.《并且》<fun()>使用函数的返回值
    miao
    1.调用函数对象
    使用函数对象
    */

立即执行函数

立即执行函数只会执行一次
//匿名函数加括号表示匿名函数是一个整体.函数不会执行
(function(){
    return 0;
});
//(匿名函数)();====>函数立即执行
(function(){
    return 0;
})();
//立即执行函数 可以传参数
(function(a,b){
    return a+b;
})(a,b);

枚举对象中的属性

  1. 函数可以作为一个对象的属性

如果一个函数作为一个对象的属性保存,那么称这个函数为 对象的方法。调用这个函数成为调用这个对象的方法啊。

本质和函数没有区别。只是名称上的区别。

比如:"xxx".toString();

  1. 枚举对象中的属性

    使用 for(var 变量 in 对象){} 循环体中有多少属性,就会循环几次
//输出属性名
(function(){
    var str = "";
    for (var n in console){
        str += n+" ,";
    }
    console.log(str);
})();
//输出属性值
(function(){
    var str = "";
    for (var n in console){
        str += console[n]+" , ";
    }
    console.log(str);
})();

作用域

全局作用域

作用域:一个变量的作用范围

  1. 全局作用域
  2. 直接编写再script标签中的JS代码,都在全局作用域
  3. 全局作用域再页面打开时创建,在页面关闭时销毁
  4. 在全局作用域中有一个全局变量window

    • 它代表一个浏览器的窗口,它由浏览器创建,可以直接使用
  5. 全局作用域

    • 创建的变量都会作为window对象的属性保存
    • 创建的函数都会作为windwo对象的方法保存
  6. 全局作用域中的变量是全局变量,

    • 在页面的任意部分都可以访问的到var a=5;
  1. 变量声明提前

使用var关键字声明的变量,会在所有的代码执行之前被声明。【但不会被赋值】

如果声明变量时不使用var关键字,则变量不会被提前声明。

console.log("a = "+a);
var a =33; //输出 a = undefined
//相当于 ====>
var a;
console.log("a = "+a);
a = 33;
//====================
console.log("a = "+a);
a = 33; //报错 “a没有定义”
  1. 函数声明提前

使用函数声明形式创建的函数function(){}会在所有的代码执行之前就被创建。可以在函数声明前创建

使用函数表达式创建的函数不会被声明提前,所以不能在声明前调用。

fun2();//输出 fun2不是一个function
fun();//输出"我是一个fun函数"
function fun(){
    console.log("我是一个fun函数");
}
var fun2 = function(){
    console.log("我是fun2函数");
}

函数作用域

  • 调用函数时创建函数作用域,函数执行完毕之后,函数作用域销毁
  • 调用一次函数就会创建一个新的函数作用域,他们之间是相互独立
  • 函数作用域中阔以访问到全局作用域变量。 在全局作用域无法访问到函数作用域的变量
  • 当在函数作用域操作一个变量时,它会先在自身作用域寻找,如果有直接使用。

    • 如果没有则向上一级作用域中寻找,直到找到全局作用域
    • 如果全局作用域中也没有,则会报错。ReferenceError
  • 在函数中要访问全局变量,阔以使用window对象。
  • 在函数中,不使用var声明的变量都会,自动设置为**全局变量**
function fun(){
    console.log("a = "+a);
}
var a =5;
fun(); //调用fun. 输出5

function fun2(){
    var b = 6;
}
console.log("b = " +b); //ReferenceError

function fun3(){
    console.log("a = "+a);
    var a = 10; //======> var a; xxxxx; a=10;
}
fun3(); //输出 未定义

function fun4(){
    a = 13;
    H = 20;
    fun5();  // a=13 ===>window.a = 13;
    function fun5(){
        console.log("a = "+a); 
    }
}
fun4(); //执行函数fun4()    
console.log("H = "+ H); //H = 20; 不会提前声明H,
函数作用域中也有函数声明提前的特性,使用var关键字声明的变量,会在函数中所有的代码执行之前被声明
function fun(){
    var a = 5;
    fun7();
    function fun7(){ //提前执行.
        console.log("a = "+a); //a = 5;
    }
}
定义形参,相当于在函数作用域中声明了变量
var a =55;
function fun9(a){
    console.log(a);
    return a;
}
fun9(); // a ===> undefined .

function getStyle() 【兼容性问题】

当浏览器是IE8时,变量getComputedStyle会首先在getStyle()函数作用域寻找有木有这个function

函数中没有,会在全局作用域寻找,也没有。则会报错。后面的代码-----------都不执行。

function getStyle(obj,name){
    if(getComputedStyle){ //是一个变量
        ----------------------
        //正常浏览器的方式,具有getComputedStyle()方法
        return getComputedStyle(obj,null)[name];
    }else{
        //IE8的方式,没有getComputedStyle()方法
        return obj.currentStyle[name];
    }
}

function getStyle(obj,name){
    if(window.getComputedStyle){ //变成了对象的属性。找不到会返回undefined
        return getComputedStyle(obj,null)[name];
    }else{
        return obj.currentStyle[name];
    }
}

函数声明

var func = new Function("console.log('构造函数');"); 这个构造方式可以使用console.log(func)输出该方法的内容。function fun(){}则不能console.log输出方法内容。
//使用function fun()
function fun(){
    var a =8;
}

//var提前声明miao 数据类型undefined。等待程序 执行完这行代码,之后miao才会定义为函数并且是一个“匿名函数”?。
console.log(typeof miao);//undefined
var miao = new Function ("return 666;");
console.log(miao); // function anoymous(){xxx}

函数的方法apply,call

call()apply()方法

  • 这两个方法都是函数对象的方法,需要通过函数对象调用。

function fun(){}

fun();=====>返回值,不是函数对象。

fun ====>函数对象

  • 对函数调用这两个方法时,都会调用函数执行

    fun(); ==== fun.apply(); ==== fun.call();

  • 在调用call和apply时可以将一个对象指定为第一个参数。

    此时,这个对象会成为函数执行时的this

var obj1 = {name:"obj1"};
var obj2 = {name:"obj2"};
function fun(){
    console.log(this.name);
}
fun.call(obj1); // obj1
  • 参数是谁,执行的对象就是
var obj1 = {name:"obj1",sayName:function (){console.log(this.name)}};
var obj2 = {name:"obj2"};
function fun(){
    console.log(this.name);
}
obj1.sayName.call(obj2); // obj2

call方法:可以将实参在对象之后传递

apply方法:需要将实参封装在数组中,再传递

function fun(a,b){
    console.log("a ="+a);
    console.log("b ="+b);
}
var obj1 = {name:"obj1",sayName:function (){console.log(this.name)}};
var obj2 = {name:"obj2"};
//`call`方法:可以将实参在对象之后传递
fun.call(obj1,3,4); // a = 3,b = 4
//apply 方法需要将实参封装到数组中
fun.apply(obj1,[3,4]); // a = 3,b = 4

arguments

  • arguments对象不是一个 Array 。它类似于Array,但除了length属性和索引元素之外没有任何Array属性。
  • 在调用函数时,传递的实参都会保存在arguments
  • arguments.length可以用来获取实参的数量
  • 所以即使不定义形参,也可以通过arguments来使用实参。

    • arguments[0] ====> 第一个实参
    • arguments[1] ====> 第二个实参
  • arguments有一个属性: callee

    • 这个属性对应一个函数对象,就是当前正在执行的函数对象
function fn( a , b){
    console.log(a+b);
    console.log(arguments.length);
    console.log(arguments.callee);
}

fn(1,3,4,5,6);
/*
4
5
[Function: fn]
*/
最后修改:2022 年 01 月 05 日
如果觉得我的文章对你有用,请随意赞赏