日期:2014-05-16  浏览次数:20426 次

JavaScript 之call , apply 和prototype 介绍


1. 前言

为什么将这三个概念放在一起说。原因是这些是会在实现js 继承会需要使用到的


2. call 和 apply

call 和 apply 的作用基本类似, 都是去执行function并将这个function 的context替换成第一个参数带入。 两者的不同是call 必须将function 的参数一一带入,而 apply  只要在第二个参数带入一个数列。
function fn( arg1, arg2,... ){
  // do something
}

fn( arg1, arg2,... );

fn.call( context, arg1, arg2,... );

fn.apply( context, [ arg1, arg2,... ]);

手册的解释:
===================================
call 方法
调用一个对象的一个方法,以另一个对象替换当前对象。

call([thisObj[,arg1[, arg2[,   [,.argN]]]]])

参数
thisObj
可选项。将被用作当前对象的对象。

arg1, arg2,  , argN
可选项。将被传递方法参数序列。

说明
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。

如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
=====================================
<!--by oscar999 2013-1-17-->  
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<script>
var func=new function(){this.a="func"}
 var newfunc=function(x){
     var a="newfunc";
     alert(this.a);
     alert(x);
 }
 newfunc.call(func,"inputParameter1"); 
 /*alert are
 * func/inputParameter1; not newfunc/inputParameter1
 */
</script>
</body>
</html>

从以上的例子可以看出, alert(this.a), 返回的是并不是当前函数里的值。


使用call 执行的速度会稍微快一些, 不过差异不大。

3.prototype

JavaScript没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instance)的区分,全靠一种很奇特的"原型链"(prototype chain)模式,来实现继承。
prototype 其实就是构造函数的一个属性。
所有实例对象需要共享的属性和方法,都放在这个对象里面;那些不需要共享的属性和方法,就放在构造函数里面。
实例对象一旦创建,将自动引用prototype对象的属性和方法。也就是说,实例对象的属性和方法,分成两种,一种是本地的,另一种是引用的。
function Person(name){
	this.name = name;
	this.gender = "male";
}
var person1 = new Person("MM");
var person2 = new Person("YY");
person1.gender = "female";
alert(person2.gender);// male
</script>

<script>
function Person(name){
	this.name = name;
}
Person.prototype.gender = "female";
var person1 = new Person("MM");
var person2 = new Person("YY");
alert(person2.gender);// male
</script>


比较以上两个例子就知道了。



4. 参考

http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_javascript.html