function showId(){
alert(this.id);
}
window.onload = function(){
var div1 = document.getElementById("div1");
div1.onclick = showId;
div1.show = showId;
div1.show();
var obj = new Object();
obj.id = "obj";
obj.show = showId;
obj.show();
}
我们可以将showId这个函数赋值给click事件,也可以赋值给任何一个对象的任何一个属性,这是也会拷贝showId这个方法的,所以我们在调用div1.show方法时,this是指向div1的,在调用obj.show时,this指向的是obj的。
3、对象冒充的原理
下面的代码是通过对象冒充方法实现的继承
复制代码 代码如下:
function ClassA(sColor){
this.color = sColor;
this.sayColor = function(){
alert(this.color);
}
}
function ClassB(sColor,sName){
this.newMethod = ClassA;
this.newMethod(sColor);
delete this.newMethod;
this.name = sName;
this.sayName = function(){
alert(this.name);
}
}
var objB = new ClassB("color of objB","name of objB");
objB.sayColor();
objB是ClassB的一个实例,objB是如何拥有color属性和sayColor方法的呢?
首先从实例化的代码看起:
var objB = new ClassB("color of objB","name of objB");
这里ClassB是个类,ClassB中的this当然就是指的objB这个对象;
在ClassB中,前三行代码会用到ClassA,这时就把ClassA看作一个函数,而不是类。
我们如果直接调用ClassA这个函数,那么很显然,ClassA中的this指的就是window对象了,所以我们先将ClassA拷贝到objB的newMethod这个属性中(this.newMethod = ClassA),
然后再调用this.newMethod,这是这个方法的owener明显的已经成了this,而ClassB中的this在当前指的是objB,所以此时ClassA中(严格的说是newMethod中,因为这是拷贝过后的,跟ClassA已经是两个方法了)的this就是指的objB,这样在通过newMethod的调用,就给objB赋值了color属性和sayColor方法。用call和apply方法来实现继承实际上也是一个原理,call和apply可以看作是改变方法的owner的方法,而这里ClassB中的前三句代码也就是起这个作用的。
四、prototype1.6中的Class.create
复制代码 代码如下:
prototype1.6中的Class.create方法大致如下:
var Class = {
create: function() {
//
function klass() {
this.initialize.apply(this, arguments);
}
//
for (var i = 0; i < properties.length; i++)
klass.addMethods(properties[i]);
//
return klass;
}
};
在使用的时候是这样的:
复制代码 代码如下:
var Person = Class.create({
initialize:function(name){
this.name = name;
},
say:function(message){
alert(this.name + ":" + message);
}
});
var aPerson = new Person("name1");
aPerson.say("hello1");
Person实际上是通过Class.create这个方法所返回的klass(klass是Class.create中的局部变量,是一个function),Class.create所传递的参数(initialize方法和say方法)传递到create方法中的properties数组中并且通过addMethods方法让klass的prototype拥有这些方法。那么最关键的地方也是最难以理解的地方是:klass中的this究竟是指的是什么。仔细想一想就不难得到答案,Person实际上就是klass,而我们在实例化Person对象的时候,是用了new关键词的:
var aPerson = new Person("name1");
这就等价于
var aPerson = new klass("name1");
虽然klass在外面不能被访问到,但是这样能很轻易的说明问题,klass是一个类而不是简单的一个函数(我们看作如此,因为用了new关键字),那么klass中的this就指的是声明的实例,在这里就是aPerson,aPerson通过klass的prototype能够拥有initialize方法和say方法,在new的过程中,也会执行klass中的代码,所以initialize在实例化的时候会执行,即构造函数。(在klass里两个this都是指的aPerson,为什么还要通过apply调用一次呢?这主要是为了传递构造函数的参数,用apply方法可以将数目不定的多个参数通过数组方便的传到initialize方法中去。)
五、再分析几个例子
从别的文章里看到的例子,我在这里分析一下:
1、运行如下代码
复制代码 代码如下: