函数的声明和函数的表达式
函数的声明
function fn(){}
这是函数声明- 带有名字的是具名函数 声明后面不需要加分号
- 函数在声明的时候并没有执行,只是把内部作为一块 存起来 当调用时候执行 函数的执行:
fn();
采用函数名加() 执行不分场合,可以放在函数声明之前 可以在函数声明之后 - 在函数声明之后不能加() 比如
function fn(){alert(1);}();
是会报错的 - 匿名函数不能莫名奇妙出现 除非在赋值 传参 场景下出现
var i=10;
function fn(){
alert(i);
}
i=11;
fn();
结果是11 代码自上而下执行
var i=10;
fn();
function fn(){
alert(i);
}
i=11;
结果是10
fn();
var i=10;
function fn(){
alert(i);
}
i=11;
结果是undefined 这个关于作用域
函数表达式
var fn = function(){};
把匿名函数作为值传递 是函数表达式 此时需要加括号 因为这是个语句- 函数想要执行 变量名加()
fn();
var fn =function ab(){
alert(1);
}
ab();
是会报错的 只是把函数作为值传递 并不是声明 执行是变量名加(); 一般赋值不取名字
- 函数表达式可以在末尾加()执行
- 把函数声明 转换成函数表达式 加括号执行
(function(){
alert(1);
})();
!function(){
alert(1);
}();
+function(){
alert(1);
}();
~function(){
alert(1);
}();
(function(){
alert(1);
}());
在匿名函数外边加括号转变为函数表达式 匿名函数立即执行(iife)
作用1 节省变量 2 私有属性的问题
函数作用
- 代码的重复使用
- 独立的代码快 不影响其他变量
<body>
<div id="box">1</div>
<div id="wrap">2</div>
<div id="content">3</div>
</body>
<script>
var oBox = document.getElementById("box");
var box2 = document.getElementById("wrap");
var box3 = document.getElementById("content");
oBox.onclick = fn;
box2.onclick = fn;
box3.onclick = fn;
function fn() {
alert(this.innerHTML);
}
</script>
需要注意的是 是点击之后执行函数 所以不能写成oBox.onclick = fn();
相当于把函数当作一个值fn传过去了
function fn() {
var a =123;
console.log(a);
}
fn();
结果是123
var a =123;
function fn() {
console.log(a);
}
fn();
结果是123
var a =123;
function fn() {
var a =346;
console.log(a);
}
fn();
console.log(a);
第一个结果是346 第二个结果是123;如果没有变量声明 会去函数外边找 但是函数外边不能影响函数内部的变量声明 函数内部的变量声明也不去影响外界
形参和实参
function fn() {//小括号里面可以放东西 我们称之为 形参 可以看作var a 没赋值
console.log(a);
}
function fn(a) {//小括号里面可以放东西 我们称之为 形参
console.log(a);
}
fn(2);//实际上的参数 实参 传递数据给形参赋值 a=2; 形参和实参一一对应
function fn(a,b) {
console.log(a+b);
}
fn(2,3,4);
不会报错 结果是5
function fn(a,b) {//var a,b
console.log(a+b);
}
fn(2);//a=2
结果是NaN
arguments
- arguments 仅仅存在于函数当中 你用与不用 他都在 是个类数组 保留着所有实参
function fn() {
var len = arguments.length;
var sum = 0;
for(var i=0;i<len;i++){
sum += arguments[i];
}
console.log(sum);
}
fn(1,2,3,4,5);
结果是15console.log(arguments.callee)
是函数本身
练习
<script>
document.onclick = fn;
function fn(x) {
alert(x);
}
</script>
如果想把参数2传入参数 怎么实现? console.log(fn(2));
结果是undefinde
<script>
document.onclick = function(){
fn(2);
};
function fn(x) {
alert(x);
}
</script>
实参里面可以放任何数据类型
<script>
function x(y) { //var y;
y();
}
x(function () {//y=function(){alert(1)}
alert(1);
})
</script>
<script>
function x(y) { //var y;
y(2);
}
x(function (a) { //y=function(a){alert(a)}
alert(a);
})
</script>
把函数当作参数传递
console.log(a=10);
结果是10 是等号右边
console.log(x=function () {
alert(1);
});
结果是等号右边 函数体本身
var x;
(x=function () {
alert(1);
})();
console.log(x);
结果还是函数体本身 x赋值就是函数体本身 第二行代码是匿名函数自执行 赋值操作的返回值是等号右边的数据
函数返回值 return
<script>
function fn() {
console.log(1);
}
console.log(fn());
</script>
结果是1 undefined
凡是运算 都有返回值 函数的执行也是一种运算 也应该有返回值
console.log(console.log(1));
结果是1 undefined 默认情况下 函数运算 “执行”的返回值是undefined
即console.log(console.log());
的结果是undefied;那么 console.log(fn());
结果可以看作是函数执行的值和fn()”执行“的运算
- 改变返回值 用return 函数运行的返回值
<script>
function fn() {
console.log(1);
return 10;
}
console.log(fn());
</script>
结果是1 10
- return除了能够确定函数的返回值以外 还能阻断函数的执行
<script>
function fn() {
return 10;
console.log(1);
}
console.log(fn());
</script>
这样遇到return后 不会执行console.log(1);直接跳出函数 那么结果是10
for (var i=0;i<100;i++){
if(i==50){
return;
}
}
这样会报错 return只能用在函数中 跳出循环用break
- return只能在函数中使用
var i=0;
function fn() {
for (;i<100;i++){
if(i===50){
return;
}
}
}
fn();
console.log(i);
结果是 50
var i=0;
function fn() {
for (;i<100;i++){
if(i===50){
break;
}
}
}
fn();
console.log(i);
结果是50
var i=0;
function fn() {
for (;i<100;i++){
if(i===50){
return;
}
}
i++;
}
fn();
console.log(i);
结果还是50
var i=0;
function fn() {
for (;i<100;i++){
if(i===50){
break;
}
}
i++;
}
fn();
console.log(i);
结果是51
- break 是for循环跳出
练习
document.onclick = fn();
function fn() {
return function () {
alert(1);
}
}
document.onclick = fn()();
function fn() {
return function () {
return function(){
alert(1);
}
}
}
对于点击事件来说加两个括号 对于函数执行来说加三个括号
写个函数 传入数值 返回一加到该数字的值
function add(x) {
if (x>1){
return x+add(x-1)
} else{
return x;
}
}
add(10);
(function add(x) {
if (x>1){
return x+arguments.callee(x-1);
} else{
return x;
}
})(10);