1.函数的定义
1.1函数语句
案例一 这个案例没有return ,这个函数返回的是 undefined
let o={
x:1,
y:2,
z:3
}
function printprops(o){
for(let p in o){
console.log(`${p} : ${o[p]}`)
}
}
console.log(printprops(o));
案例二 计算两个笛卡尔坐标(x1,y1)和(x2,y2)之间的距离, 这个函数返回的是Math.sqrt(dx*dx+dy*dy)
function distance(x1,y1,x2,y2){
let dx=x1-x2;
let dy=y1-y2;
//Math.sqrt() 函数返回一个数的平方根
return Math.sqrt(dx*dx+dy*dy)
}
console.log(distance(5,7,7,9))
计算阶乘的递归函数(调用自身的函数)
x!的值是从x到x递减的值的累乘
比如x为4 最后的结果4*3*2*1
function factorial(x){
if(x<=1){
return 1;
}else{
return x*factorial(x-1);
}
}
console.log(factorial(4));
1.2函数表达式
let squary=function(x){
return x*x;
}
//函数表达式可以包含名称,这在递归时很有用
let f=function fact(x){
if(x<=1){
return 1;
}else{
return x*fact(x-1)
}
}
console.log(f(5));//120
//函数也可以作为参数传给其他函数
let data=[5,100,367,293,31,20];
data.sort(function(a,b){
return a-b;
})
console.log(data);//[5, 20, 31, 100, 293, 367]
//函数表达式有时定义后立即调用
let tensquared=(function(x){
return x*x;
})(13);
console.log(tensquared);//169
2.函数命名规则
2.1嵌套函数,在js中函数可以嵌套在其他函数中,内嵌的函数不能出现在循环,条件判断
function hypotenuse(a,b){
function square(x){
return x*x;
}
return Math.sqrt(square(a)+square(b))
}
console.log(hypotenuse(5,5));
3.函数调用
四种方式可以来调用js函数
● 作为函数
● 作为方法
● 作为构造函数
● 通过它们的call() 和apply()的方式调用
3.1作为函数
let o={
x:1,
y:2,
z:3
}
function printprops(o){
for(let p in o){
console.log(`${p} : ${o[p]}`)
}
}
console.log(printprops(o));
3.2作为方法调用
var o = {
method: function () {
console.log(1)
}
}
o.method();
注●如果嵌套函数作为函数调用,其this值不是全局对象(非严格模式)就是undefined(严格模式)
let o={
m:function(){
var self=this;
console.log(this==o);
f();
function f(){
console.log(this);//false window undefined
console.log(self==o);//true
}
}
}
o.m()
3.3 作为构造函数调用
如果函数和方法调用之前加关键字new,它就构成了构造函数
let o=new Object(); let o=new Object;
3.4通过它们的call() 和apply()的方式调用
改变this指向 下面的案例this指向了sum
call和apply()区别是传递的参数不同
function add(c,d){
console.log(this)
return this.a+this.b+c+d;
}
let sum={
a:1,
b:2
}
let res= add.call(sum, 10, 2);//this 的指向是sum
console.log(res);
let res1=add.apply(sum,[20,21]);//44 this 的指向是sum
console.log(res1)
4.函数的实参和形参
4.1.可选形参 当调用函数的时候传入的实参比函数声明时指定的参数个数要少,剩下的形参都将设置为 undefined
function getPropertyNames(o,a){
a= (a == undefined) ? []:a;
for(let item in o){
a.push(item)
}
return a;
}
let o={
x:1,
y:2,
z:3
}
let p={
q:4
}
let res=getPropertyNames(o);
console.log(res);// ['x', 'y', 'z']
let res1=getPropertyNames(p,res);
console.log(res1);//['x', 'y', 'z', 'q']
4.2可变的实参列表:实参对象
可以通过arguments获取实参的个数
function f(x,y,z){
console.log(arguments.length);
}
f(1,2)
callee 和 caller 可以通过callee 递归的调用自身
function f(x,y,z){
console.log(arguments.callee);//
}
f(1,2);
将对象的属性作为实参
function arraycopy(from,form_start,to,to_end){
console.log(from,form_start,to,to_end)
}
function easycopy(obj){
arraycopy(obj.form,obj.form_start,obj.to,obj.to_end)
}
easycopy({form:'a',form_start:'b',to:'c',to_end:'d'});
5 作为值的函数
作为值的函数
function square(x){
return x*x;
}
let s=square;
square(2);//4
s(2);//4
//案例二
function add(x,y){return x+y;
}
function substrac(x,y){
return x-y;
}
function mutiplay(x,y){
return x*y
}
function divide(x,y){
return x/y
}
function operate(operator,operand1,operand2){
return operator(operand1,operand2);
}
console.log(operate(add,operate(add,2,3),operate(mutiplay,3,4)));//17
6.闭包
当一个函数嵌套另外一个函数,外部函数将嵌套的函数对象作为函数值返回,这就是闭包
let scope='global scope';function checkscope(){
let scope='local scope';
function f(){
return scope;
}
return f();
}
console.log(checkscope());//local scope
function counter(){
let n=0;
return{
count:function(){ return n++; },
reset:function(){ n=0; }
}
}
var c=counter();
var d=counter();
console.log(c.count());//0
console.log(d.count());//0
console.log(c.reset());
console.log(c.count());//0
console.log(d.count());//1
ss
网友评论