//创建函数对象的两种方法
var addNumbersA = new Function('num1','num2','return num1 + num2');
console.log(addNumbersA(1,2));//3
var addNUmbersB = function (num1, num2) {return num1 + num2;};
console.log(addNUmbersB(1,2));//3
/*Function()构造走函数实例化函数对象的四种模式
Function()构造函数采用不定数量的参数,但Function()构造函数的最后一个参数是一个包含具有函数体语句的字符串
不推荐直接利用Function()构造函数,因为JS将使用eval()来解析包含函数逻辑的字符串,这样可能出现代码设计缺陷
使用new关键字的Function()构造函数创建函数对象,
与仅使用构造函数创建函数对象有相同的效果
直接调用Function()构造函数时没有创建闭包*/
var addFunction = new Function('num1','num2','return num1 +num2');
var addFunction2 = new Function('num1,num2','return num1 + num2');
var addFunction3 = function(num1,num2) {return num1 + num2};
function addFunction4 (num1,num2) {return num1 +num2};
console.log(addFunction(1,2),addFunction2(1,2),addFunction3(1,2),addFunction4(1,2));//3 3 3 3
//Function()属性(不包括继承的属性和方法):prototype
/*Function()对象实例属性和方法
实例属性:arguments,constructor,length
实例方法:apply(),call(),toString()
*/
//如果函数没有指定返回值,则返回undefined(所有函数都要有一个返回值)
var code = function(){console.log('coding')};
console.log(code());//undefined
console.log(code() === undefined);//true
/*JS中函数既是一个对象又是一个值。函数可以储存在一个变量
数组或函数中,也可以将函数传递给函数,并由函数返回。
函数还拥有属性。*/
var funcA = function(){};
//调用方式:funcB[0]
var funcB = [function(){}];
//调用方式:funcC.method or funcC['method'];
var funcC = {code : function(){}};
//函数可以作为参数传递,也可以作为返回值返回
var funcD = function(func){
return func;
};
//此处funcD中的函数作为参数
var funcE = funcD(function(){console.log('coding is fun.')});
funcE();//coding is fun
funcE.study = 'javascript';
console.log(funcE.study);//javascript
/*调用函数时,参数是将值传递给函数作用域的工具。
JS中省略参数是合法的*/
//this和arguments适用于所有函数
var test = function () {
/*即使定义时未指定参数,调用时发送参数,
可以依靠传递给函数的arguments数组来访问参数*/
return arguments[0] + arguments[1];
}
console.log(test(1,2));
var test1 = {
name : 'fltenwall',
love : 'coding',
work : function () {console.log(this)}
};
test1.work();//输出整个test1对象
var test2 = function(){console.log(this)};
test2();//输出window对象
var test3 = function test3 () {
console.log(arguments.callee);//callee对当前执行函数自我引用
}();//()是函数自我调用(执行);输出test3()
var test4 = function(a,b,c,d,e){
return arguments.length;//用于获取函数被“调用”时发送给函数的参数数量
};
console.log(test4());//输出为0
var test5 = function(a,b,c,d,e){
return test5.length;//获取函数所需要的参数总数量
}
console.log(test5());//输出为5
var test6 = function(a,b,c,d,e){
return arguments.callee.length;
}
/*与书中结果不一致,书中说到argument.length已被废弃,
因此需要通过callee先获取函数调用再用length
获取调用时传入的参数数量,
而实际测试的结果是与functionName.length结果一致*/
console.log(test6());//输出为5
//利用arguments数组可以重新定义函数参数
num1 = 3;
num2 = 3;
var test7 = function(num1,num2) {
arguments[0] = 5;
arguments[1] = 5;
console.log(arguments[0],num1);//输出5,5,num1的值已被改变
}
//可以在函数执行的任意位置用return取消函数执行
var test9 = function (num1,num2) {
if(typeof num1 !== 'number' || typeof num2 !== 'number'){
return 'Not a number';
}
return num1 + num2;
}
console.log(test9(3,4));//输出7
// console.log(test10('3','4'));//报错
//定义函数的四种方式
//1.函数构造函数方式,最后一个参数是函数逻辑
var functest1 = new Function('val1','val2','return val1 + val2');
//2.函数语句定义方式
function functest2(val1,val2) {
return val1 + val2;
}
//3.函数表达式定义方式
var functest3 = function(val1,val2) {
return val1 + val2;
}
//4.命名函数表达式形式
var functest4 = function functest4 (val1,val2) {
return val1 + val2;
}
//输出5,5,5,5
console.log(functest1(2,3),functest2(2,3),functest3(2,3),functest4(2,3));
//调用函数的四种模式
//1.函数模式
var funcall1 = function () {return 'coding'};
console.log(funcall1());//输出coding
//2.作为其他函数的方法而调用
var funcall2 = {funcall2 : function () {return 'coding'}};
console.log(funcall2.funcall2());
//3.构造函数模式
var funcall3 = function () {
this.name= 'fltenwall',
this.age = 22,
this.love = 'coding',
this.work = function () {return this.love};
};
var funcall4 = new funcall3();//通过funcall3构造函数调用
console.log(funcall4);//输出funcall4对象和属性
console.log(funcall4.work());//输出coding,执行了构造函数内部方法函数
//4.apply()和call()方法,调用其他对象上的方法函数
var funcall5 = {
funcall6 : function () {
console.log(this.name,arguments[0],arguments[1]);
}
}
//创建对象flten和wall
var flten = {name : 'flten'};
var wall = {name : 'wall'};
//在flten对象上调用funcall6函数
funcall5.funcall6.call(flten,'flten','wall');//输出flten,flten,wall
//在wall对象上调用funcall6函数
funcall5.funcall6.apply(wall,['ften','wall']);//输出wall,flten,wall
/*call()和apply()之间的区别是函数调用时,
call()传递分开的参数,apply()传递参数组成的数组*/
//匿名函数主要用于将函数作为参数传递给另一个函数
var anon = function (f) {
f();//调用传入的匿名函数
}
anon(function () {console.log('coding')});//输出coding
//函数自调用
var self = function () {console.log('coding is fun.')}();
//使用构造函数Function()创建的函数无法自调用
var self2 = new Function('x','y','return x + y')();//无任何输出
//自调用匿名函数的几种方式
(function () {
console.log('I love coding.');
})();//输出I love coding
//也可以传入参数
(function (code) {
console.log(code + ' is fun')
})('coding');//输出coding is fun
(function (love) {
console.log('I love ' + love);
}('coding'));//输出I love coding
!function (language) {
console.log('This is ' + language);
}('javascript');//输出This is javascript
+function (language) {
console.log('This is ' + language);
}('Python');//输出Python
-function (language) {
console.log('This is ' + language);
}('Java');//输出This is Java
//一种错误的写法
// function (date) {console.log('Today is ' + date)}('3.24');//报错
//函数嵌套
var nested = function () {
var nested2 = function () {
var nested3 = function () {
var nested4 = function () {
console.log(this);//嵌套函数的this指向window对象
}();
}();
}();
}();//输出window对象
//给函数传递函数,并从函数返回函数
//传入一个匿名函数并返回
var nested = function (f) {
return f;
}
var trans = nested(function () {console.log('Coding is interesting.')});
/*执行流程:
1.匿名函数传给nested函数,并被nested函数返回
2.trans变量引用nested函数
3.trans作为函数引用执行
*/
trans();//输出Coding is interesting.
//函数可以在被定义之前使用,也成为函数提升
var hoisting = function () {
askName();
function askName () {
console.log("'What's your name?" );
}
}();
console.log(add(1,2));
function add (x,y) {
return x + y;
}
/*被定为"函数表达式"的函数没有被提升,
以下代码将报错提示adding函数未定义*/
/*
adding();
var adding = function () {
console.log('Talk is easy,show me the code.');
}
*/
/*构造函数实例化的函数对象也不会被提升,
只有定义为"函数表达式"形式的函数才会被提升*/
/*
adding(2,3)
var adding = new Function('x','y','x+y');
*/
//函数递归
var recursion = function (num) {
console.log(num);
num--;
if(num < 0) {return false};
recursion(num);
}
recursion(5);
//匿名函数递归
//第一种方式
(function (num) {
console.log(num);
num--;
if(num < 0) {return false};
recursion(num)
})(5);
//第二种方式
(function (num) {
console.log(num);
num--;
if(num < 0) {return false};
arguments.callee(num);
})(5);
《JavaScript启示录》笔记——Function()
最新推荐文章于 2022-04-25 17:07:42 发布