《JavaScript启示录》学习笔记——第4章 Function()

心情:自己挖的坑,哭着也要填完。(>_<)~~~~


4.1 Function()对象概要

函数是代码语句的容器,使用圆括号操作符()来调用。

var addNumbersA = new Function('num1', 'num2', 'return num1 + num2');

console.log(addNumbersA(2, 2)); // 输出 4

// 也可以使用字面量
var addNumbersB = function(num1, num2) {return num1 + num2;};

console.log(addNumbersB(2, 2)); // 输出 4

从最基本的形式来说,函数只是可执行语句的唯一作用域。

4.2 Function()参数

var addFunction = new Function('num1', 'num2', 'return num1 + num2');

var timesFunction = new Function('num1,num2', 'return num1 * num2');

console.log(addFunction(2,2),timesFunction(2,2)); // 输出 '2 2'

var addFunction = function(num1, num2) {return num1 + num2;}; 

function addFunction(num1, num2) {return num1 + num2;} 

4.3 Function()属性和方法

属性

  • prototype

4.4 Function对象实例属性和方法

实例属性

  • arguments
  • constructor
  • lenth

实例方法

  • apply()
  • call()
  • toString()

4.5 函数总有返回值

所有函数都要返回一个值,如果不指定要返回的值,则返回值是undefined。

var sayHi = function() {
    return 'Hi';
};

console.log(sayHi()); // logs "Hi"

var yelp = function() {
    console.log('I am yelping!');
}

console.log(yelp() === undefined);

4.6 函数是“一等公民”(不仅语法,还有值)

在javaScript中,函数是一个对象,也是一个值。
函数可以存储在一个变量,数组或者对象中。函数可以传递给函数,并由函数返回。函数拥有属性,因为它是一个对象。

var funcA = function(){}; // 调用方式: funcA()
var funcB = [function(){}]; // 调用方式: funcB[0]()
var funcC = {method: function(){}}; //调用方式 funcC.method() or funcC['method']()

var funcD = function(func){
    return func
};

var runFuncPassedToFuncD = funcD(function(){console.log('Hi');});

runFuncPassedToFuncD();

var funcE = function(){};
funcE.answer = 'yup'; // 实例化属性
console.log(funcE.answer); // 输出 'yup'

4.7 函数的参数传递给

调用函数时,参数是将值传递给函数作用域的工具。

var addFunction = function(number1, number2) {
    var sum = number1 + number2;
    return sum;
}

console.log(addFunction(3, 3)); //logs 6

4.8 this 和 arguments 适用于所有函数

arguments是一种类数组对象,他包含所有传递给参数的对象。

var add = function() {
    return arguments[0] + arguments[1];
};

console.log(add(4, 4)); // returns 8

this关键字是对包含函数的对象的引用。

var myObject1 = {
    name: 'myObject1',
    myMethod: function(){console.log(this.name);}
};

myObject1.myMethod(); // logs 'myObject1'

var myObject2 = function(){console.log(this);}; 

myObject2(); // logs Window

4.9 arguments.callee属性

arguments的callee属性,它是指对当前函数的引用。
自我引用——该属性可以用于从函数的作用域内引用函数。

var foo = function foo() {
    console.log(arguments.callee); // 输出 foo()
    // callee 可以对 foo 函数进行递归调用 ( arguments.callee())
}();

4.10 函数实例的length属性和arguments.length

  • Function()实例的length属性,可以获得函数所需要的参数总量
  • arguments.length给出的是调用时发送给函数的参数数量
  • arguments.callee.length
var myFunction = function(z, s, d, e, r, m, q) {
    return myFunction.length;
};

console.log(myFunction()); //输出 7

var myFunction = function(z, s, d) {
    return arguments.length;
};

console.log(myFunction()); // 输出 0 因为没有传入任何参数

4.11 重定义函数参数

var foo = false;
var bar = false;

var myFunction = function(foo, bar) {
    arguments[0] = true; // 方法1:使用arguments索引
    bar = true; // 方法2:直接为参数指定一个新值
    console.log(arguments[0], bar); // 输出 true true
}

myFunction();

4.12 代码执行完成前取消函数执行

在函数的任意点上通过使用return关键字来取消函数执行。

var add = function(x, y) {
    // 如果不是数字,返回错误
    if (typeof x !== 'number' || typeof y !== 'number') {return 'pass in numbers';}
    return x + y;
}
console.log(add(3,3)); // 输出 6
console.log(add('2','2')); // 输出 'pass in numbers'

4.13 定义函数(语句、表达式或构造函数)

定义函数有三种不同的方式:函数构造函数,函数语句和函数表达式。

/* 函数构造函数:最后一个参数是函数逻辑,之前都是参数 */
var addConstructor = new Function('x', 'y', 'return x + y');

// 函数语句
function addStatement(x, y) {
    return x + y;
}

// 函数表达式
var addExpression = function(x, y) {
    return x + y;
};

console.log(addConstructor(2,2), addStatement (2,2), addExpression (2,2));

//命名函数表达式
var add = function add (x, y) { return x + y; }

4.14 调用函数(函数、方法、构造函数或call()和apply())

使用4种不同场景或模式调用函数:

  • 作为函数
// 函数模式
var myFunction = function(){return 'foo'};
console.log(myFunction()); // log 'foo'
  • 作为方法
// 方法模式
var myObject = {myFunction: function(){return 'bar';}}
console.log(myObject.myFunction()); // log 'bar'
  • 作为构造函数
// 构造函数模式
var Cody = function(){
    this.living = true;
    this.age = 33;
    this.gender = 'male';
    this.getGender = function() {return this.gender;};
}
var cody = new Cody(); // 通过Cody构造函数调用
console.log(cody); // 输出 cody 对象和属性
  • 使用apply()或者call()
// apply() and call() 模式
var greet = {
    runGreet: function(){
        console.log(this.name,arguments[0],arguments[1]);
    }
}

var cody = {name:'cody'};
var lisa = {name:'lisa'};

//在 cody 对象上调用 runGreet 函数
greet.runGreet.call(cody,'foo','bar'); //输出 cody foo bar

//在 lisa 对象上调用 runGreet 函数
greet.runGreet.apply(lisa, ['foo','bar']); //输出 lisa foo bar

/* 注意 call() 和 apply() 之间的区别是函数调用时,参数传递的不同。前者传递多个分开的参数,后者传递多个参数组成的数组 */

4.15 匿名函数

匿名函数是一种没有给出标识符的函数。
匿名函数主要用于将函数作为参数传递给另一个函数。

// 创建一个函数来执行匿名函数
var sayHi = function(f){
    f(); // 调用匿名函数
}

// 将匿名函数作为参数传递
sayHi(function(){console.log('hi');}); // 输出 'hi'

4.16 自调用的函数表达式

在定义一个函数表达式后,加上圆括号,便可立即调用改函数表达式。

var sayHi = function () { console.log('Hi'); } ();// 输出'Hi'

4.17 自调用的匿名函数表达式

创建一个自调用的匿名函数语句,这叫做自调用的匿名函数。

// 最经常使用的匿名函数
(function(msg) {
    console.log(msg);
})('Hi');

// 看起来有点不一样,但效果一样
(function(msg) {
    console.log(msg)
}('Hi'));

// 更简短的方式
!function sayHi(msg) {console.log(msg);}('Hi');

// 注意,下面的的代码不行
//function sayHi() {console.log('hi');}();

注意:根据ECMAScript标准,如果要立即调用函数,需要使用函数外面的圆括号(或任何将函数转换为表达式的符号)。

4.18 函数可以嵌套

函数可以无限嵌套在其他函数内部

var foo = function () {
    var bar = function () {
        var goo = function () {
            console.log(this);
        } ();
    } ();
} ();

4.19 给函数传递参数,从函数返回函数

由于函数是一个值,并且可以将任何类型的值传递给函数,因此函数可以被传递给函数,也可以返回其他函数。(高阶函数)

var foo = function(f) { //传入函数
    return f; //返回函数
}

var bar = foo(function() {console.log('Hi');});

bar(); //输出 'Hi'

函数可以像其他任何值一样被传递。

4.20 函数定义之前调用(函数提升)

在代码运行之前,函数语句其实已经被编译器解释,并添加至执行堆栈/上下文。

var speak = function() {
    sayYo(); // sayYo() 还没有被定义,但依然可以执行并输出 'yo'
    function sayYo() {console.log('Yo');}
}(); 

注意:被定义为“函数表达式”的函数没有被提升,只有“函数语句”被提升。

4.21 函数可以调用自身(递归)

函数调用自身是完全合法的。启动一个函数,然后通过该函数调用本身。

function cutDownForm (num) {
    console.log(num);
    num--;
    if (num < 0) { return false; }
    cutDownForm (num);
}
cutDownForm (2);

匿名函数可以通过arguments.callee进行递归

(function (num) {
    console.log(num);  
    num--;
    if (num < 0) { return false; }
    arguments.callee(num);    
} (2));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值