JS是前端开发的基础,也是ajax技术要使用必不可少的一环,本文主要说一下,关于JS中函数的知识.

函数

JS中的函数相当于Java中的方法

函数的定义有两种方式:
1.函数声明:

function f1(){}
function f2(a,b){return a+b}

2.函数表达式:

var f3=function(){}
var f4=function(a,b){return a+b}

定义总结:
1)在函数的定义中,无论用哪种方式定义,函数名都可看做变量
2)定义函数的形式参数时,只需要给名字即可不用var.

使用函数需要调用,将实参传给形参如:

f2(1,2);

注意:
调用函数时,参数的赋值从左往右进行赋值,若实参的个数小于形参的个数,那么没被赋值的形参值为undefined(不是null)
如果调用函数时,有undefined参与运算,结果为NaN(不是一个数)

函数的自调用

函数的自调用指的是,函数声明完了之后,马上进行调用,只能使用一次,有两种写法:

1.

(function(){
    console.log("自调用");
})();

2.

(function(){
    console.log("自调用");
}());

主要区别就是最后的括号的放置位置.

函数自调用,可以用于JS框架中的声明变量.

回调函数

function f01(callback){
    callback(100);
};

f01(function(result){
    console.log(result);
});

当执行上边的代码时,最后会在控制台显示"100".

上边是定义函数,下边是调用函数,下边在调用上边的f01函数,而参数callback又回调了实参传入的function.

总结:当把一个函数作为实参传递给一个函数时,这个作为实参传递的函数就被称为回调函数,上述例子中callback形参指向回调函数.

全局变量和局部变量

全局变量

JS中和Java一样,都有全局变量和局部变量的含义,

全局变量:所有函数之外的变量

var a=100;
var a=200;
function a(){
    console.log("a()");
}

在上述代码中后输入的a=200会覆盖a=100;函数a()会覆盖a=200,这就是由于他们所取的名字都一样,后面的a会覆盖前边的a---也就是污染.

所有的全局变量都是window对象(BOM)所有.

函数名也对一个全局变量同样会覆盖变量或方法.

局部变量

var m=100;
function f(){
    var m=200;
    m--;
    console.log(m);
}

和全局变量相对,函数内的变量叫局部变量,在函数内生效,上述代码中,最终控制台会显示199,这是因为---当全局变量和局部变量重名时,遵循局部优先原则.

函数外不可以直接访问函数内的变量或函数.

对象

在JS中,除了5中基本数据类型(number/String/boolean/null/undefined)之外,其他的都是对象类型.

对象的书写格式有两种:
1.简写:

var s1={"id":100,"name":"xiaowang"};

这就是一个对象,其中:前为属性名,:后为属性值.

属性名默认可以不适用""引入,字符串和日期值必须要用""引入.

2.非简写:

var s2=new Object();
s2.id=101;
s2.name="xiaoli";

这种就需要先new一个object对象,再往里进行定义赋值操作.

后两步操作是将定义属性与给属性赋值同时进行.

JS中对象适用于封装属性和方法的一个结构体,属性方法用","分隔!

var s3={"id":102,"name":"xiaohu","play":function(){console.log("play")}};
s3.id;//通过变量访问对象属性
s3.play();//通过对象变量调用对象方法

构造函数

如果要创建大量同样属性名的对象该怎么办?
就需要引入构造函数
JS中定义构造函数如下:

function student(id,name){
    this.id=id;
    this.name=name;
    this.play=function(){console.log("play")};
}

方法内部要访问方法外属性要使用this,构造方法中this指向调用这个方法的对象.
有了构造方法后,创建对象会基于构造方法去构建对象,并将实际参数传递给形式参数:

var s4=new student(104,"xiaozhao");

在上述例子中,在构造函数中尽量不要去再定义函数---因为这会导致,每次构建对象时,构造函数内的函数还会多额外开启一个空间.

原型对象

引入

如果不能再构造函数中再定义函数,那么如果构造函数创建的对象需要有函数怎么办呢?

可能会想到直接添加并赋值:

s1.play=function(){console.log("play")};

这样确实再对象创建了函数并赋值了,但是这个函数是s1私有的,其他构造函数构建的对象是拿不到这个函数的.

那么就有另一种方法,先看一下这种方法:

student.prototype.play=function(){
    console.log("play");
}

简单来看,这段代码就是通过一个函数名(student)获取了一个对象(prototype),然后在对象中添加了一个函数(play)并赋值.

当我们需要由构造函数构建的对象都有共享的一些函数,我们可以基于prototype方式去定义.

然后当我们使用变量(属性或方法)时,我们会现在自己对象内部查找是否有私有的变量,没有再去prototype中查找.

原型对象

prototype成为原型变量,

prototype:{constructor:f}

JS中每个构造函数内都内置了一个prototype对象,再这个对象中可以定义基于构造函数构建的所有对象所共享的属性和方法.

基于构造方法构建的对象内部都有一个属性为"_ proto _",它指向从构造函数中继承的prototype对象

JS中通过继承方式来实现代码的重用性就要借助于prototype对象

var point=function(x,y){
    this.x=x;
    this.y=y;
}
var p1=new point(10,20);
console.log(p1._ptoto_==point.ptototype);//true

_proto _和prototype指向的是同一个对象(原型对象).

原型对象上添加多个函数

var point=function(x,y){
    this.x=x;
    this.y=y;
}
point.prototype={
    setx:function(x){
        this.x=x;
    },
    getx:function(){
        return x;
    }
}

通过上述方法就可以在原型对象上添加多个函数(setx/getx)

不再通过prototype.函数名的方式,而是prototype={},引入一个json格式的JS对象,再把函数作为属性添加,中间以","分隔.


迈克丝
85 声望5 粉丝

一步一步学技术,踏踏实实涨经验,兴趣广泛,广交好友,希望大家多多指正/批评.