Java Script 函数基础知识

来源:互联网 发布:数据服务的公司 编辑:程序博客网 时间:2024/05/01 12:56
  • 函数的定义
Funtion 构造器: var funcName = new Function( [argname1, [... argnameN,]] body );

简单函数定义: [是JS提供的一种语法糖,即通过字面量来创建函数]
var add = function add(m,n) {
alert(m+n);
}
事实上function关键字会调用Function来new一个对象,并将参数表和函数体准确的传给Funtion的构造器。
即等同于
var add = new Function("x", "y", "alert(x+y)");

通常来说,在全局作用域内声明一个对象,只不过是对一个属性赋值而已,比如上例中的add函数,事实上只是为全局对象添加了一个属性,属性名为add,而属性的值是一个对象,即funtion(x,y){alert(x+y);},理解这一点很重要,这条语句在语法上跟  Var str = "This is a string"; 并无二致。都是给全局对象动态的增加一个新的属性,如此而已。
function p(){
print("invoke p by ()");
}
 
p.id = "func";
p.type = "function";
 
print(p);
print(p.id+":"+p.type);
print(p());
如上例所示,p虽然引用了一个匿名函数(对象),但同时又可以拥有属性,完全跟其他对象一样,运行结果如下:
function(){
print("invoke p by()");
}
func:funtion
invoke p by ()

  • 函数的参数(arguments)

JavaScript 在处理函数的参数时,与其他的编译型语言不一样,解释器传递给函数的是一个类似于数组的内部值,叫arguments,在这个函数对象生成的时候就被初始化了。arguments并不是一个数组,只是与数组相似。arguments除了拥有length属性,数组的所有属性和方法都不具备。
用arguments来实现一个累加的函数
function sum(){
var total = 0;
for(var i=0; i<arguments.length; i++){ // arguments.length返回sum函数调用时传递参数的个数
total += arguments[i];
}
return total;
}
alert("sum: " + sum(1, 3, 2, 4));

  • 函数的调用
[1] 方法调用 (所谓方法就是将一个函数赋给一个对象的属性)
//定义一个函数
function hello(name) {
alert('hello,' + name);
};
var user = {};
//赋值给user的sayHi属性
user.sayHi = hello;
//方法调用
user.sayHi('张三');

[2] 函数调用
alert("hello");
var result = add(1, 2);
普通的函数调用和方法调用的一个区别:在"普通的函数调用"方式中,函数的调用上下文(this的值),为全局对象(非严格模式)或者undefined(严格模式)。而在"方法调用"方式中,this指向当前对象。利用这一特性,我们可以在方法不需要明确的返回值时,直接返回this,从而实现"方法链"。如jquery中常见的:
$('#btn_edit').css({color:red}).show();
嵌套函数中的this:嵌套函数中,内层函数不会继承外层函数的this,即当内层函数作为方法调用时,内层函数的this指向当前调用对象;当内层函数作为函数调用时,this的值为全局对象(非严格模式)或者undefined(严格模式)。怎样在内层函数中访问外层函数的this呢?通常将this保存在一个局部变量中,通过变量来访问:
var obj = {
f : function() {
var self = this;
console.log(this === obj);//true,this指向当前对象
 
f1();
 
function f1() {
console.log(this === obj);//false,this为全局对象或者undefined
console.log(self === obj);//true,self指向外层this,即当前对象
}
}
};

[3] 构造器调用
当使用new关键字创建一个对象时,即调用了构造函数。构造函数若没有形参,可以省略圆括号:
var obj = new Object();
//等价于
var obj = new Object;
调用构造函数,创建了一个新对象,这个对象会成为该构造函数的调用上下文(this的值):
function User(name) {
this.name=name;
console.debug(this);
}
 
var user = new User('张三');


[4] Call 调用
var name = 'A';
var user = {
name : 'B'
};
 
function showName() {
alert(this.name);
}
 
showName();//A,this为全局对象
showName.call(user);//B,this为user对象

[5] Apply调用
// 定一个累加方法。如sum(1,2,3,4...)
// 该方法位于window执行环境中。
var displayName = function(){
alert("sum的执行环境: " + typeof(this));
alert("Name: " + this.name); // 取出当前执行环境中name属性
}
// 定一个Person对象
var Person = {
name: "zhangsan"
};
displayName.apply(Person);
call() 和 apply() 可以用来间接调用函数。call() 的第一个参数用来指定调用上下文(即this的值),后面的参数是传入调用函数的实参。apply() 和 call() 类似,区别在于,后面的实参需要以数组的形式传递(可将当前函数的arguments数组直接传入)。

  • 函数的异常
function add(a, b){ // 定义一个加法函数
// 如果传递的参数不是数字类型,则抛出一个异常信息
if(typeof a != 'number' || typeof b != 'number'){
throw {
'name' : "typeError", // 属性是自定义的,名字可以任意取
'message': "add方法必须使用数字作为参数"
};
}
return a + b;
}
(function(){
// 捕获add方法可能产生的异常
try{
add(10, "");
} catch(e){
// 一个try语句只有一个catch语句,如果要处理多个异常,则通过异常的name属性来区别
// 判断异常的类型
if(e.name === "typeError"){
alert(e.message);
}
}
})();


1 0