您的位置:首页 > 移动开发

javascript中call,apply,arguments,callee,caller的用法

2015-05-24 17:31 597 查看
<%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<!--
apply call 方法,是javascript 实现类继承重要的内容,也是原型链的重要内容;
javascript 的基础, javascript 原型链
javascript中call、apply、argument、callee、caller
call 方法: call 调用一个对象的一个方法,以另一个对象替换当前对象;
call([thisObj[,arg1[,arg2[,[....argN]]]]])

参数:
thisObj 可选项,将被用作当前对象的对象;
arg1, arg2, arg3,....argN 可选择项,将被传递方法参数序列;

说明:
call 方法可以用来代替另一个对象[构造函数]调用一个方法,call 方法可以将一个函数的对象上下文从初始的上下文改变
为由 thisObj 指定的新对象;
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj;
-->
<script type="text/javascript">
function person(name, age, sex) // javascript 构造函数
{
this.name = name;
this.age = age;
this.sex = sex;
}

function student(name, age, sex, universtiy, major)
{
this.universtiy = universtiy;
this.major = major;
person.call(this, name, age, sex); // person.call(student, argments....)
}

var john = new student("john", 20, "male", "MIT", "webdeveloper"); // 添加实例
// alert(john.name + ' is ' +  john.age); // john is 20
// 从上面的函数来看, 按理说 student 并没有 age 这个属性,但是为什么john.age 会是 20 呢?
// 原因就是person.call(student, name, age, sex);从结果来看, call 多少有点继承的味道;
// A.call(B, argument, argument2 ....) 结果就是B 继承了A,对 B进行实例化后,B 里面继承了A的属性和方法;

function person2(name, age, sex)
{
this.name = name;
this.age = age;
this.sex = sex;
this.say = function(){alert("my name is " + name);};
}

function student2(name, age, sex, university, major)
{
this.universtiy = university;
this.major = major;
person2.call(this, name, age, sex);
}

var cathy = new student2("cathy", 20, "male", "MIT", "webdeveloper");
alert(cathy.age + ', she major in  ' + cathy.major);
cathy.say();

// 只有"方法"才能使用call 方法,其他对象或属性没有,这里指的方法 即:typeof(any) == 'function'
// 其它typeof 非function 的都没有call 方法,比如 Array 数组就没有call 方法
// 当然, call 方法不是必须在构造函数体内:
function person3(name, age, sex)
{
this.name = name;
this.age = age;
this.sex = sex;
this.say = function() {alert("my name is "+ this.name);};
}

function student3(name, age, sex, university, major)
{
this.name = "inner";
this.university = university;
this.major = major;
}

var john = new student3("john", 20, "male", "MIT", "webdeveloper");
var person3 = new person3();
person3.say.call(john); // my name is inner []

// 同时继承多个类[javascript 构造函数]
function parent(father, mother)
{
this.father = father;
this.mother = mother;
this.tell = function() {alert(this.father + " ," + this.mother);};
}

function person4(name, age, sex)
{
this.name = name;
this.age = age;
this.sex = sex;
this.say = function () {alert("my name is " + this.name);};
}

function student4(name, age, sex, university, major)
{
this.name = "inner";
this.university = university;
this.major = major;
parent.call(this);
person4.call(this, name, age, sex);
}

var michael = new student4("michael", 20, "male", "MIT", "webdeveloper");
alert(michael.sex);
michael.father = "Bob Micheal";
michael.mother = "Mary michal";
michael.tell();

// 通过parent.call(this);person.call(this); student同时继承了parent和person的属性及方法
// apply 方法,应用某一个对象的一个方法,用一个对象替换当前对象;
// 语法: apply([thisObj[,argArray]])
// 参数 thisObj 可选项,将被用作当前对象的对象;
// argArray 可选项,将被传递给该函数的参数数组;
// 说明:
// 如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个TypeError;
// 如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj 并且无法传递任何参数
// apply 方法与 call 的区别在于,call 传递参数直接列出来就可以了,而apply 传递的参数需要把参数放在数组里面;
function person6(name, age, sex)
{
this.name = name;
this.age = age;
this.sex = sex;
this.say = function(){alert("my name is " + this.name);};
}

function student6(name, age, sex, university, major)
{
this.university = university;
this.major = major;
person6.apply(this, [name, age, sex]); //apply与call的区别,传递参数的方法不同
}

var jimmy = new student6("jimmy", 20, "male", "MIT", "webdeveloper");
alert(jimmy.sex);
jimmy.say();

// argument 对象
// argument 是javascript 的内置对象,它代表正在执行的函数和调用它的函数的参数;
// 使用方法:[function[.arguments]
]
// 其中 function 是可选项,当前正在执行的 Function 对象的名字;
// n 是必选项,要传递 Function 对象的从 0开始的参数值索引
// 不能显示创建 arguments 对象,arguments 对象只有函数开始才可以使用,函数 arguments 对象并不是一个数组
// 访问单个参数的方法与访问数组元素的方式相同,索引n 实际上是 arguments 对象 0...n 属性中其中一个参数..
// 加载自调用函数--> arguments 在 javascript 关键字
(function argTest(a, b, c, d) {
alert("函数需要" + argTest.length +"个参数"); // 反馈 javascript 函数参数的个数
alert("已经传入的参数为:" + arguments.length + "个");
for (var i = 0; i < arguments.length; i++)
{
document.writeln(arguments[i]);
}
})(1,2,3,4);

// callee 属性; callee 属性是arguments 的一个属性,返回方法的正文:
// func.arguments.callee = func;
(function argTest(a,b,c,d){
alert("函数需要 "+argTest.length+" 个参数");
alert("已经传入的参数为:"+arguments.length+"个");
document.writeln("参数分别为:");
for(var i=0;i<arguments.length;i++){
document.writeln(arguments[i]);
}
alert(arguments.callee); //增加此句,将alert显示出整段代码
})(1,2,3,4);

// callee 为arguments 属性,返回整个代码,可以轻松实现递归调用
function fact(n)
{
if(n<=0){
return 1;
}else{
return n*arguments.callee(n-1);  //轻松实现递归调用
}
}
alert(fact(5)); // 求阶乘

// caller 方法:
// caller 属性是方法的一个属性,返回当前调用该方法的方法;
// 如果在A 方法中调用了B 方法, 在A 方法执行的过程中,在B 函数中存在B.caller 等于A 的方法体;
// 说明
// 对于函数来说,caller 属性只有在函数执行时才有定义,假如函数是由顶层调用的,那么 caller
// 包含的就是 null,假如在字符串上下文中使用 caller 属性,那么结果和 functionName.toString 相同,也就是说,
// 显示的是函数的反编译文本;
function callerDemo()
{
if (callerDemo.caller)
{
var a = callerDemo.caller.toString();
alert(a);
}
else
{
alert("this is a top function");
}
}
function handleCaller()
{
callerDemo();
}
handleCaller(); //返回handleCaller方法体
callerDemo();  //返回this is a top function

</script>
</head>

<body>

</body>
</html>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: