《JavaScript启示录》笔记——Function()

	//创建函数对象的两种方法
	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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值