定义函数
声明函数
/*
function 函数名称(传入参数...) {
要执行的功能语句
}
*/
function square(number) {
return number * number;
}
/*
若函数参数传入的值为原始数值类型
函数对传入参数的修改,不会影响该值在其他地方的值
若为引用类型,就会改变该值的原始值,在其他地方的使用此值,也会改变
*/
function myFunc(theObject) {
theObject.make = 'Toyota';
}
var mycar = {make: 'Honda', model: 'Accord', year: 1998};
var x, y;
x = mycar.make; // x gets the value "Honda"
myFunc(mycar);
y = mycar.make; // y gets the value "Toyota"
// (the make property was changed by the function)
函数表达式
var square = function(number) { return number * number; };
var x = square(4); // x gets the value 16
var factorial = function fac(n) { return n < 2 ? 1 : n * fac(n - 1); };
console.log(factorial(3));
function map(f, a) {
var result = []; // Create a new Array
var i; // Declare variable
for (i = 0; i != a.length; i++)
result[i] = f(a[i]);
return result;
}
var f = function(x) {
return x * x * x;
}
var numbers = [0, 1, 2, 5, 10];
var cube = map(f,numbers);
console.log(cube);
// [0, 1, 8, 125, 1000]
呼叫函数
注意:function hoisting只工作于声明式的函数中,不能被使用于以函数表达式宣告的函数。
console.log(square(5));
/* ... */
function square(n) { return n * n; }
console.log(square); // square is hoisted with an initial value undefined.
console.log(square(5)); // TypeError: square is not a function
var square = function(n) {
return n * n;
}
函数自己可以呼叫自己
function factorial(n) {
if ((n === 0) || (n === 1))
return 1;
else
return (n * factorial(n - 1));
}
var a, b, c, d, e;
a = factorial(1); // a gets the value 1
b = factorial(2); // b gets the value 2
c = factorial(3); // c gets the value 6
d = factorial(4); // d gets the value 24
e = factorial(5); // e gets the value 120
函数范围
在函数中声明的变量,使用范围只限制在函数中,不能在函数声明范围之外使用。
// The following variables are defined in the global scope
var num1 = 20,
num2 = 3,
name = 'Chamahk';
// This function is defined in the global scope
function multiply() {
return num1 * num2;
}
multiply(); // Returns 60
// A nested function example
function getScore() {
var num1 = 2,
num2 = 3;
function add() {
return name + ' scored ' + (num1 + num2);
}
return add();
}
getScore(); // Returns "Chamahk scored 5"
递归函数:函数声明中,出现对函数自身的呼叫。
function loop(x) {
if (x >= 10) // "x >= 10" is the exit condition (equivalent to "!(x < 10)")
return;
// do stuff
loop(x + 1); // the recursive call
}
loop(0);
function walkTree(node) {
if (node == null) //
return;
// do something with node
for (var i = 0; i < node.childNodes.length; i++) {
walkTree(node.childNodes[i]);
}
}
函数的嵌套
function addSquares(a, b) {
function square(x) {
return x * x;
}
return square(a) + square(b);
}
a = addSquares(2, 3); // returns 13
b = addSquares(3, 4); // returns 25
c = addSquares(4, 5); // returns 41
若嵌套中的函数,构成了函数功能的终结,那么在呼叫外层函数时,可以同时指定外层函数和内层函数所需要传入的参数。
function outside(x) {
function inside(y) {
return x + y;
}
return inside;
}
// fn_inside = outside(3); // Think of it like: give me a function that adds 3 to whatever you give
// it
// result = fn_inside(5); // returns 8
result1 = outside(3)(5); // returns 8
function A(x) {
function B(y) {
function C(z) {
console.log(x + y + z);
}
C(3);
}
B(2);
}
A(1); // logs 6 (1 + 2 + 3)
/*
名称冲突
若嵌套的函数的参数,同外层函数中声明的变量的名称发生冲突
那么嵌套的函数的参数值,以传入的值为优先
*/
function outside() {
var x = 5;
function inside(x) {
return x * 2;
}
return inside;
}
outside()(10); // returns 20 instead of 10
var pet = function(name) { // The outer function defines a variable called "name"
var getName = function() {
return name; // The inner function has access to the "name" variable of the outer
//function
}
return getName; // Return the inner function, thereby exposing it to outer scopes
}
myPet = pet('Vivie');
myPet();
var createPet = function(name) {
var sex;
return {
setName: function(newName) {
name = newName;
},
getName: function() {
return name;
},
getSex: function() {
return sex;
},
setSex: function(newSex) {
if(typeof newSex === 'string' && (newSex.toLowerCase() === 'male' ||
newSex.toLowerCase() === 'female')) {
sex = newSex;
}
}
}
}
var pet = createPet('Vivie');
pet.getName(); // Vivie
pet.setName('Oliver');
pet.setSex('male');
pet.getSex(); // male
pet.getName(); // Oliver
var getCode = (function() {
var apiCode = '0]Eal(eh&2'; // A code we do not want outsiders to be able to modify...
return function() {
return apiCode;
};
})();
getCode(); // Returns the apiCode
使用参数列表对象
function myConcat(separator) {
var result = ''; // initialize list
var i;
// iterate through arguments
for (i = 1; i < arguments.length; i++) {
result += arguments[i] + separator;
}
return result;
}
// returns "red, orange, blue, "
myConcat(', ', 'red', 'orange', 'blue');
// returns "elephant; giraffe; lion; cheetah; "
myConcat('; ', 'elephant', 'giraffe', 'lion', 'cheetah');
// returns "sage. basil. oregano. pepper. parsley. "
myConcat('. ', 'sage', 'basil', 'oregano', 'pepper', 'parsley');
函数参数
从ECMAScript2015开始,有两种参数类型default parameters & rest parameters
Default parameters
JavaScript函数参数的默认值为:undefined
function multiply(a, b) {
b = typeof b !== 'undefined' ? b : 1;
return a * b;
}
multiply(5); // 5
function multiply(a, b = 1) {
return a * b;
}
multiply(5); // 5
Rest parameters
此种机制可以向传入数组一样,传入多个参数给函数。
function multiply(multiplier, ...theArgs) {
return theArgs.map(x => multiplier * x);
}
var arr = multiply(2, 1, 2, 3);
console.log(arr); // [2, 4, 6]
箭头函数
var a = [
'Hydrogen',
'Helium',
'Lithium',
'Beryllium'
];
var a2 = a.map(function(s) { return s.length; });
console.log(a2); // logs [8, 6, 7, 9]
var a3 = a.map(s => s.length);
console.log(a3); // logs [8, 6, 7, 9]
function Person() {
this.age = 0;
setInterval(() => {
this.age++; // |this| properly refers to the person object
}, 1000);
}
var p = new Person();
JavaScript与定义函数
eval() 评估代码执行结果,返回字符串
console.log(eval('2 + 2'));
// expected output: 4
console.log(eval(new String('2 + 2')));
// expected output: 2 + 2
console.log(eval('2 + 2') === eval('4'));
// expected output: true
console.log(eval('2 + 2') === eval(new String('2 + 2')));
// expected output: false
isFinite() 判断传入的值是否是有限的数值
function div(x) {
if (isFinite(1000 / x)) {
return 'Number is NOT Infinity.';
}
return "Number is Infinity!";
}
console.log(div(0));
// expected output: "Number is Infinity!""
console.log(div(1));
// expected output: "Number is NOT Infinity."
isNaN() 判断传入的值是否是非数字
function milliseconds(x) {
if (isNaN(x)) {
return 'Not a Number!';
}
return x * 1000;
}
console.log(milliseconds('100F'));
// expected output: "Not a Number!"
console.log(milliseconds('0.0314E+2'));
// expected output: 3140
parseFloat() 将传入的字符串参数转换为浮点数
function circumference(r) {
return parseFloat(r) * 2.0 * Math.PI;
}
console.log(circumference(4.567));
// expected output: 28.695307297889173
console.log(circumference('4.567abcdefgh'));
// expected output: 28.695307297889173
console.log(circumference('abcdefgh'));
// expected output: NaN
parseInt() 将传入的字符串参数转换为整数
function roughScale(x, base) {
var parsed = parseInt(x, base);
if (isNaN(parsed)) { return 0 }
return parsed * 100;
}
console.log(roughScale(' 0xF', 16));
// expected output: 1500
console.log(roughScale('321', 2));
// expected output: 0
decodeURI() 解码由encodeURI()编码的统一资源标识符(URI)
var uri = 'https://mozilla.org/?x=шеллы';
var encoded = encodeURI(uri);
console.log(encoded);
// expected output: "https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B"
try {
console.log(decodeURI(encoded));
// expected output: "https://mozilla.org/?x=шеллы"
} catch(e) { // catches a malformed URI
console.error(e);
}
decodeURIComponent() 解码由encodeURIComponent()编码的统一资源标识符组件
function containsEncodedComponents(x) {
// ie ?,=,&,/ etc
return (decodeURI(x) !== decodeURIComponent(x));
}
console.log(containsEncodedComponents('%3Fx%3Dtest')); // ?x=test
// expected output: true
console.log(containsEncodedComponents('%D1%88%D0%B5%D0%BB%D0%BB%D1%8B')); // шеллы
// expected output: false
encodeURI() 编码统一资源标识符
var uri = 'https://mozilla.org/?x=шеллы';
var encoded = encodeURI(uri);
console.log(encoded);
// expected output: "https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B"
try {
console.log(decodeURI(encoded));
// expected output: "https://mozilla.org/?x=шеллы""
} catch(e) { // catches a malformed URI
console.error(e);
}
encodeURIComponent() 编码统一资源标识符组件
// encodes characters such as ?,=,/,&,:
console.log(encodeURIComponent('?x=шеллы'));
// expected output: "%3Fx%3D%D1%88%D0%B5%D0%BB%D0%BB%D1%8B"
console.log(encodeURIComponent('?x=test'));
// expected output: "%3Fx%3Dtest"