让JS的'this'变回AS3的'this'
刚刚从AS3转成JS的同学,语法上会有很多不适应,比如没有继承,类,接口等OOP语法,不过最大的不适应,某过于他变幻莫测的‘this’。那今天我就来让JS的‘this’变回AS3的‘this’。
首先我先介绍2种this的不同之处,AS3中的this,没有特殊操作的话,不管在什么地方都指向类实例化的对象。但是js却不是,JS在构造函数中,也是指向类实例化的对向,其他地方一般指向调用这个方法的对象,而直接function,没有调用对象时,指向的是全局对象。
由于JS的‘this’这样的特性,所以他的this经常的变,特别是在侦听中,因为侦听的方法参数实际上是回调函数,调用对象肯定不是当前类实例对象,甚至不是侦听对象,那怎么办呢?这个简单,侦听前保存当前的this指向就好了,比如下面:
var _this = this;
xxx.addEventListener("click",function (){
_this.xxxxx();
})
上面的代码实在流水账式的代码中保持this的方法,那如果在oop写法的类中呢?看下面:
var cls = {};
(function() {
function People(){
this.Container_constructor();
this.name = "金四胖";
this.shape = new createjs.Shape();
this.shape.graphics.beginFill("#ff0000")
this.shape.graphics.drawRect(0,0,200,200);
this.shape.graphics.endFill();
this.addChild(this.shape);
var _this = this;
this.shape.addEventListener("click",_this._say = function (event)//_this._say是为了保存引用 用来remove事件
{
console.log(this,_this)//这时候this指向已经不对了,但是_this是对的
_this.say()
})
// this.shape.addEventListener("click",this._say = _this.say.bind(this))//这样也可以 更简单
// this.shape.addEventListener("click",this.say);//如果使用这个方式,say中的this会变成全局对象
}
var p = createjs.extend(People,createjs.Container);
//p中所有的方法都可以在实例化中的对象调用
p.say = function ()
{
console.log("我说话了,我的名字是" + this.name);
this.shape.removeEventListener("click",this._say)//删除侦听
}
cls.People = createjs.promote(People, "Container");
}());
var canvas,stage;
function init() {
canvas = document.getElementById("mainView");
stage = new createjs.Stage(canvas);
stageBreakHandler();
var people = new cls.People();
stage.addChild(people);
createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNCHED;
createjs.Ticker.setFPS(30);
createjs.Ticker.addEventListener("tick", stageBreakHandler);
}
function stageBreakHandler(event)
{
stage.update();
}
在People这个类中,大家看到了熟悉的构造,继承,这个就是createjs标准类的写法,在方法外面套用一个方法的办法使得say这个方法内部的this可以获得实例对象,这就跟AS3一样了,而把这个方法保存起来,使得如果需要去除事件时,可以引用这个方法remove。
点击下面的链接可以测试一下this的引用:
发表评论