`
roc08
  • 浏览: 224063 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Extjs4 Web Application Development Cookbook学习笔记四

阅读更多
原创翻译,欢迎纠错,转载请注明出处

4.函数作用域
    Javascript开发者面临的一个很大的问题就是函数作用域的问题,因为this在js中是随着函数不同而变化的,并不像java类中指向全局。每个函数内部的this都是不同的。
    强烈建议先学习下js的作用域规则(参见《Javascript权威指南》),这里我们将简要介绍作用域是什么?怎么变化?对我们的代码有什么影响?

a.什么是函数作用域Scope
作用域指的是一段正在执行的代码的上下文环境,他决定了什么样的变量对其是可用的。
js有两种类型的作用域:全局作用域和局部作用域。全局作用域下定义的函数和变量在任何地方都是可以访问的。最常见的例子是document和window变量。局部变量和函数是指在一个函数内部定义的,不能被函数外部访问。
作用域链是js解析变量的一种方式,当试图访问一个函数中的变量时,如果这个变量不是在函数内定义的,那么js引擎将遍历作用域链(函数链 原型链)找到与之同名的变量,如果没有则抛出一个错误,这意味着局部的变量会优于全局变量被找到和使用。

下面我们将举几个例子说明作用域是什么工作的

1.第一个例子很简单,我们声明一个全局变量,并通过alert访问它
var myVar = 'Hello from Global Scope!';
alert(myVar); //alerts 'Hello from Global Scope!'


2.  下面这个例子会弹出两个alert,第一个打印Hello from Global Scope!,第二个打印Hello from MyFunction!,说明在函数myFunction中可以访问和修改全局变量
var myVar = 'Hello from Global Scope!';
function myFunction(){
  myVar = 'Hello from MyFunction!';
}
alert(myVar); //alerts 'Hello from Global Scope!'
myFunction();
alert(myVar); //alerts 'Hello from MyFunction!'


3.  我们在myFunction中定义一个局部变量myVar,这样局部变量myVar的作用域是函数myFunction,这样在执行alert(myVar)时将会打印出Hello Global Scope!而不是Hello from MyFunction!,因为这样是相当于在函数内部定义了一个局部变量而不是改变了全局变量的值,且函数外面的alert也不能访问到函数中的myVar变量。而函数中的alert访问的就是函数中定义的myVar了,根据上面说的,他会先访问局部变量。
var myVar = 'Hello Global Scope!';
function myFunction(){
  var myVar = 'Hello from MyFunction!';
  alert(myVar);
}
alert(myVar); //alerts 'Hello from Global Scope!'
myFunction(); //alerts 'Hello from MyFunction!'
alert(myVar); //alerts 'Hello from Global Scope!'

4. 最后我们将演示this关键字的用法,this关键字无处不在,为我们提供了一个访问当前代码执行的上下文环境的引用。下例中使用MyClass的构造器新建一个对象,通过观察log中的this值发现其实新建对象的引用,这意味中我们可以在这个对象上定义属性,并使得他们的作用域只在这个对象内部,不会被对象外部访问到。
function MyClass(){
   console.log(this);
}
var myClass = new MyClass();

5. 如果我们在构造器中添加一个属性,当对象创建后我们可以在构造器中将其alert出来,但是如果我们试图在MyClass作用域外访问this.myProperty,他将不存在,因为这里的this指的是浏览器对象window。
function MyClass(){
    console.log(this);
    this.myProperty = 'Hello';
}
var myClass = new MyClass();
alert(myClass.myProperty); // alerts 'Hello'
alert(this.myProperty); // alerts 'undefined'


ExtJs中的作用域

在Extjs中我们需要关心的是确保我们的函数在正确的类的作用域中执行。例如默认情况下Button的点击事件的作用域是自身,而如果我们想要他的handler事件在其父类中执行,例如grid Panel中,则需要将作用域scope指定到grid panel。
下面通过几个例子看一下extjs是怎么做的

1. 定义两个对象,每一个都有一个属性和方法。
var cat = {
    sound: 'miaow',
    speak: function(){
        alert(this.sound);
    }
};
var dog = {
    sound: 'woof',
    speak: function(){
        alert(this.sound);
    }
};
cat.speak(); // alerts 'miaow'
dog.speak(); // alerts 'woof'


2. 使用 Ext.bind 方法强制使得dog对象的speak方法在cat对象中执行
Ext.bind(dog.speak, cat)(); // alerts 'miaow'


工作原理
Ext.bind方法通过创建包装函数,重写了speak方法的作用域,强制 赋为传进来的第二个参数,使得这个新的函数能够立即执行或者存储在一个变量中稍后执行。通过使用bind函数我们重新定义this为函数传入的第二个参数,这就是为什么上例2中执行狗狗的speak方法会发出猫咪的叫声。

More
对于事件处理函数来说确保函数的作用域正确是尤其重要的。Extjs提供了一个scope的配置项可用于设置事件处理函数执行的作用域。
例如下例中,我们定义了一个button和一个click事件,点击click后会弹出一个alert,显示当前作用域下的text属性值。
var button = Ext.create('Ext.button.Button', {
    text: 'My Test Button',
    listeners: {
        click: function(button, e, options){
            alert(this.text);
        }
    },
    renderTo: Ext.getBody()
});
button.show();

默认情况下,this指向button本身,但是如果我们想要这个函数在另一个作用域中执行,例如在下面的作用域中执行。
var exampleObject = { text: 'My Test Object'};

我们最初吃的反应是使用bind方法,如下
listeners: {
    click: Ext.bind(function(button, e, options){
        alert(this.text);
    }, exampleObject)
}

上面的方法执行的很好,功能也正确,不过我们有更简单的方法,通过配置scope实现。
listeners: {
    click: function(button, e, options){
        alert(this.text);
    },
    scope: exampleObject
}

如果你在listeners中配置scope,那么对于所有的事件都会生效,如果只想针对某个事件指定其scope,可以这样写:
listeners: {
    click: {
        fn: function(button, e, options){
            alert(this.text);
        },
        scope: this
    },
    afterrender: {
        fn: function(button, options){
            // do something...
        },
        scope: otherObject 
    }
}
分享到:
评论

相关推荐

    Ext JS 4 Web Application Development Cookbook

    Ext JS 4 Web Application Development Cookbook by Andrew Duncan and Stuart Ashworth (Aug 24, 2012) $49.99 Paperback Order in the next 11 hours and get it by Tuesday, Mar 19. More Buying Choices - ...

    ExtJS4.Cookbook.2012

    ExtJS4.Web.Application.Development.Cookbook.2012

    Extjs4.0学习笔记

    ExtJS4学习笔记(四)---Grid的使用 ExtJS4学习笔记(五)---Grid分页 ExtJS4学习笔记(六)---多表头Grid ExtJS4学习笔记(七)---带搜索的Grid(SearchGrid) ExtJS4学习笔记(八)---Grid多选/全选 ExtJS4学习笔记(九)...

    ExtJS学习笔记.doc

    ExtJS学习笔记.docExtJS学习笔记.docExtJS学习笔记.docExtJS学习笔记.doc

    ExtJS4中文教程2 开发笔记 chm

    ExtJS4学习笔记(十四)--- ComponentQuery ExtJS4学习笔记(四)---Grid的使用 Extjs4开发笔记(三)——菜单的实现 Extjs4开发笔记(二)——框架的搭建 Extjs4开发笔记(五)——动态grid Extjs4开发笔记(四)——实现登录...

    extjs4.x学习笔记

    从开发大型的web后台或者企业管理系统来看,ExtJs3的缺陷还是比较明显的,从ExtJs4 开始引入了MVC架构,从而能够从容的组织系统的JS文件了。 从ExtJs5开始则引入了MVVC架构。 从网上资料来看,多数都是停留在ExtJs3...

    extJs 2.1学习笔记

    23. extJs 2.0学习笔记(Ext.Panel篇四) 62 24. extJs 2.0学习笔记(组件总论篇) 66 25. extJs 2.0学习笔记(Ext.Element API总结) 69 26. extJs 2.0学习笔记(Element.js篇) 73 27. extJs 2.0学习笔记(DomHelper.js篇) ...

    extjs4 web应用程序开发指南源代码

    extjs4 web应用程序开发指南源代码,国内首本

    Extjs 5 学习笔记

    Extjs 5 学习笔记,在网上下载整理好的。

    extjs4 学习笔记源码

    exjts4 学习笔记源码,源码包含windws,hbox,vbox和Grid的应用,其中grid介绍比较多。下载解压后,部署后就可以使用,所有代码均在demo文件夹下。更多extjs4教程,请关注http://www.mhzg.net

    Extjs3.0 cookbook

    一本非常好的extjs教程,Extjs 3.0 cookbook

    ExtJs学习笔记,共30讲

    23. extJs 2.0学习笔记(Ext.Panel篇四) 62 24. extJs 2.0学习笔记(组件总论篇) 66 25. extJs 2.0学习笔记(Ext.Element API总结) 69 26. extJs 2.0学习笔记(Element.js篇) 73 27. extJs 2.0学习笔记(DomHelper.js篇) ...

    ExtJS4 Web应用程序开发指南(第2版).zip

    ExtJS Web应用程序开发指南(第2版)对EXTJS4.0深入讲解,免责声明,只有前3章内容(extjs 4.0)

    extjs4.0学习笔记

    自己总结的extjs4学习笔记,自己总结的extjs4学习笔记,自己总结的extjs4学习笔记,

    ExtJs4+Web参考项目

    ExtJs4+Web参考项目 EXTJS4 WEB开发 EXT EXTJS EXT4

    EXTJS学习笔记,自己学习的过程,不多但是实用

    EXTJS 学习笔记 ROY EXTJS学习笔记,自己学习的过程,不多但是实用

    extjs3 Cookbook

    extjs3 cookbook 一本非常好的extjs教程

    ExtJs简明教程+Extjs学习笔记

    ExtJs简明教程+Extjs学习笔记,来源网络,免费奉送,我讨厌需要资源分~

Global site tag (gtag.js) - Google Analytics