Javascript this关键字使用分析(2)


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、运行如下代码

复制代码 代码如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjzdjx.html