函数
2020-10-29 09:35:19
函数的声明:
- 命令式声明:
1 function print(s) { 2 console.log(s); 3 } 4 //调用 5 print()
- 变量赋值式声明:
【匿名函数】
var print = function(s) { console.log(s); };
【构造函数】
var add = new Function( 'x', 'y', 'return x + y' ); // 等同于 function add(x, y) { return x + y; }
【加上函数名,函数名只在函数内部有效,函数体外部失效】
1 var print = function x(){ 2 console.log(typeof x); 3 }; 4 5 x 6 // ReferenceError: x is not defined 7 8 print() 9 // function
var f = function f() {}; - 函数名的提升:
命令声明函数,会将函数当做一个变量,相当于变量的声明;
var 变量=function 变量(){}======重复声明了,所以报错
函数的属性和方法
- name属性:返回函数名

承认自己菜吧!!!这特么就是一个传参,你墨迹了半天!!!
test函数用了一个方法f.name;test(myFunc)值就是myFunc.name - length属性:返回函数预期传入的参数个数
- toString()方法:返回一个函数源码的字符串
函数作用域
- 作用域:全局作用域+函数作用域(ES6块级作用域)
变量存在的范围在其他区块中声明的都是全局变量(比如if(){})
- 函数内部的变量提升:
和外部一样,在函数内部中,如果是其他区块声明一个变量,那这个变量就是在这个函数内部的一个全局变量
- 函数本身的作用域:
f函数,return x();x函数输出的是变量a
参数:允许省略
- 参数就是函数运行时候提供的外部数据,length属性是指函数预定的参数个数【function x(a,b,c){...}】

- 传递方式(传参)

- 同名参数:取最后出现的值
function f(a, a) { console.log(a); } f(1, 2) // 2 f(1)// undefined
- arguments对象:在函数体内读取所有的参数,只有在函数体内可以使用
arguments[0]读取函数体第一个参数;
严格模式下(在函数体内部使用'use strict'),argument对象和函数参数无关,不会影响到实际的函数内参数;
arguments.length可以查看调用函数的时候带了几个参数;
将arguments对象转为数组:
callee属性:调用函数自身;在严格模式禁用!创建一个变量,数组 变量或者方法添加 返回数组选定的元素 使用arguments对象
var args = Array.prototype.slice.call(arguments);
创建一个数组,遍历arguments,输出元素到数组 var args = []; for (var i = 0; i < arguments.length; i++) { args.push(arguments[i]); }
闭包:读取函数内部的变量,在函数的内部再定义一个函数,这个函数就是闭包;
外层函数每次运行,都会生成一个新的闭包,而这个闭包又会保留外层函数的内部变量,所以内存消耗很大。因此不能滥用闭包,否则会造成网页的性能问题
- 函数
f1的返回值就是函数f2,由于f2可以读取f1的内部变量,所以就可以在外部获得f1的内部变量了;
函数f2
function f1() { var n = 999; function f2() { console.log(n); } return f2; } var result = f1(); result(); // 999
- 闭包的另一个用处,是封装对象的私有属性和私有方法
function Person(name) { var _age; function setAge(n) { _age = n; } function getAge() { return _age; } return { name: name, getAge: getAge, setAge: setAge }; } var p1 = Person('张三'); p1.setAge(25); p1.getAge() // 25
函数立即调用:通常是对匿名函数这么做;
目的:不必为函数命名,避免污染全局变量;形成一个作用域,封装一些外部无法读取的私有变量
- 函数名():print();
- 表达式:
var f = function f() {}() - 不要让function出现在行首【function出现在行首说明是语句,不是表达式】:
(function(){ /* code */ }()); // 或者 (function(){ /* code */ })();
eval命令:接受字符串作为一个参数,并将字符串作为语句执行,命令里面不能是其他命令,否则报错
- 案例
eval('var a = 1;'); a // 1
- 如果字符串无法作为语句执行,那么报错
eval('3x') // Uncaught SyntaxError: Invalid or unexpected token
- 如果参数不是字符串,那么会原样返回
eval(123) // 123
不推荐使用,在当前作用域内注入代码,容易造成风险,修改当前作用域的变量值,
因此规定,使用eval命令的函数内部必须是严格模式下
eval别名调用:作用域是全局作用域,调用的是全局的变量

eval是别名调用,所以即使它是在函数中,它的作用域还是全局作用域,因此输出的a为全局变量。这样的话,引擎就能确认e()不会对当前的函数作用域产生影响,优化的时候就可以把这一行排除掉。
你的代码量决定了你的薪资水平!
浙公网安备 33010602011771号