让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的引用:
发表评论