@Dale-Lin
2017-12-26T07:24:47.000000Z
字数 3875
阅读 1242
JavaScript
函数是一系列语句组成的一个整体,用于执行某一特定任务。
构造函数函数名首字母应该大写,并且使用 new 操作符调用。
function sayHellow() {document.write('Hellow hope!');}
//前面可以声明函数sayHello();//后面也可以声明函数
function size(width,height){return width*height;}//定义函数size时使用了形参height和width,return返回后面表达式计算的值var size1 = size(8,10);//调用函数size时使用了实参8和10,此时size1是80var WIDTH = 8;var HEIGHT = 10;var size2 = size(WIDTH,HEIGHT);//WIDTH和HEIGHT是储存了实参的变量
function culSize(width,height,depth){var area = width*height;var volume = area*depth;var sizes = [size,volume];return sizes;}//在这个函数中sizes储存了一个数组var area1 = culSize(6,6,6)[0];var volume2 = culSize(6,6,6)[1];//调用时加入了实参,并且调用返回数组中的不同值
var area = function (width,height) {return width*height;};var size3 = area(2,3);
这类函数没有函数名,在解释器经过时执行一次
var area = ( function () {var width = 2;var height = 3;return width*height;}());//最外层的括号表明这个函数是一个表达式,函数语句块结束后的括号令解释器经过时直接执行此函数
函数内的arguments对象存在一个叫callee的属性,该属性是一个指针,指向拥有该arguments对象的函数。如下一个典型的阶乘函数:
function factorial(num){if (num<=1){return 1;}else (return num*arguments.callee(num-1);)}//使用arguments.callee(num-1)替代factorial(num-1),降低函数名与程序的耦合度
函数内另一个特殊对象是this,引用函数执行的环境对象,在全局作用域下,即为window对象。(严格模式下undefined)
window.color = "red";var o = {color: "blue",};function sayColor(){alert(this.color);}sayColor(); //redo.sayColor = sayColor;o.sayColor(); //blue
在ECMAScript中,函数也是一种对象,因此函数拥有属性和方法。
每个函数都有两个属性:length 和 prototype
length length表示函数预设的命名参数个数:
function sayName(name){alert(name);}function sum(num1,num2){return num1+num2;}function sayHi(){alert('Hi');}console.log(sayName.length); //1console.log(sum.length); //2console.log(sayHi,length); //0
prototype toString()、valueOf() 等方法实际上都保存在 prototype 名下,只是通过各自对象的实例来进行访问。 prototype 属性无法枚举,不能使用 for-in 发现。每个函数都包含两个原生方法:apply() 和 call() 。这两个方法都用于在特定的作用域中调用某函数:
apply() Function.prototype.apply()
/* 改变函数作用域 */window.color = "red";var o = {color: "blue"};function logColor(){console.log(this.color)}logColor(); //redlogColor.apply(o, ); //blue/* 传递参数 */function sum(num1,num2){return num1+num2;}function callSum1(num1, num2){return sum.apply(this, arguments); //使用arguments传入callSum1的全局环境和参数}function callSum2(num1, num2){return sum.apply(this, [num1,num2]); //使用Array实例传入callSum1的全局环境和参数}console.log(callSum1(5,10)); //15console.log(callSum2(10,10)); //20
call() Function.prototype.call() apply() 作用相同,但接受参数的方式不同。
function sum(num1,num2){return num1+num2;}function callSum(num1, num2){return sum.call(this, num1, num2);}console.log(callSum(10,10)); //20
与apply()一样,在扩充作用域上的优势在于——对象和方法之间没有任何耦合关系。
bind() bind(),该方法会创造一个function实例,其this值与传给bind()作为参数的对象/函数的this值绑定。
window.color = "red";var o = {color: "blue"};function sayColor(){console.log(this.color);}var objectSayColor = sayColor.bind(o);console.log(objectSayColor); //blue
toString() or toLocaleString() 语法
eval(string)
接收以字符串形式表示的一串JS代码,并立刻执行(evaluates)。
解析器发现调用eval()方法时,将传入的参数执行结果插入到原代码位置,因此这段代码与eval()具有相同的作用域。
eval("function sayHi(){ alert('hi');}");sayHi(); //"hi"
即使是在eval()方法内声明的代码,在eval()代码相同的作用域下也可以被访问。
如果eval()接收的参数不是字符串,eval()会将参数直接插入原位置,而不会执行。
eval(new String("2+2")); //return "2+2"eval("2+2"); //return 4var expression = new String("2+2");eval(expression.toString()); //return 4
如果 间接 地使用eval(),它将在全局作用域下起作用(忽略当前作用域):
function test(){var x = 2, y = 4;console.log(eval("x+y")); //直接调用,使用function本地作用域,6var geval = eval;console.log(geval("x+y")); //间接调用,使用全局作用域,throws ReferenceError,x、y未定义}
在eval()中创建的任何变量或函数都不会被提升,因为在解析代码时,它们包含在一个字符串中,只有在eval()执行的时候创建。
eval()执行时调用js解析器,因此运行效率比其他替代方案慢。
return 可以使函数提前返回,当 return 执行时,函数立即返回而不再执行余下语句。
一个函数如果没有返回值,则返回 undefined 。