原创翻译,欢迎纠错,转载请注明出处
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 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 - ...
### ExtJS 4 Web Application Development Cookbook #### 一、书籍简介与价值 《ExtJS 4 Web Application Development Cookbook》是一本全面介绍了ExtJS 4框架的实用指南。本书由Stuart Ashworth和Andrew Duncan...
### ExtJS4 Web Application Development Cookbook (2012) #### 知识点概览 - **书籍概述**:本书提供了一系列实用的食谱,旨在帮助读者掌握Ext JS 4的各种功能,从基本特性到高级应用设计。 - **作者介绍**:本书...
ExtJS4学习笔记(四)---Grid的使用 ExtJS4学习笔记(五)---Grid分页 ExtJS4学习笔记(六)---多表头Grid ExtJS4学习笔记(七)---带搜索的Grid(SearchGrid) ExtJS4学习笔记(八)---Grid多选/全选 ExtJS4学习笔记(九)...
ExtJS学习笔记.docExtJS学习笔记.docExtJS学习笔记.docExtJS学习笔记.doc
ExtJS4学习笔记(十四)--- ComponentQuery ExtJS4学习笔记(四)---Grid的使用 Extjs4开发笔记(三)——菜单的实现 Extjs4开发笔记(二)——框架的搭建 Extjs4开发笔记(五)——动态grid Extjs4开发笔记(四)——实现登录...
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应用程序开发指南源代码,国内首本
myeclipse下开发的,数据库是mysql,带sql文件,改下密码就可运行。这是别人分享的毕业项目,需要的拿走。。。学习的好资料。
EXTJS4 是一款强大的JavaScript框架,用于构建富客户端Web应用程序。EXTJS4的学习文档旨在帮助开发者掌握这一框架,尤其对于初学者来说...通过深入学习和实践,开发者可以熟练掌握EXTJS4,创建功能丰富的Web应用程序。
exjts4 学习笔记源码,源码包含windws,hbox,vbox和Grid的应用,其中grid介绍比较多。下载解压后,部署后就可以使用,所有代码均在demo文件夹下。更多extjs4教程,请关注http://www.mhzg.net
### Extjs 5 学习笔记之 SenchaCmd 深入解析 #### 一、SenchaCmd 的简介 SenchaCmd 是一个跨平台的命令行工具,它为基于 ExtJS 和 Sencha Touch 应用程序的开发周期提供了全面的支持。从创建应用程序的基础结构到...
ExtJS Web应用程序开发指南(第2版)对EXTJS4.0深入讲解,免责声明,只有前3章内容(extjs 4.0)
EXTJS 3.0 Cookbook 是一本专注于EXTJS框架的教程,旨在帮助开发者深入学习并掌握EXTJS 3.0版本的各项功能和最佳实践。EXTJS是一个强大的JavaScript库,用于构建富客户端Web应用程序,以其丰富的组件库、强大的数据...
ExtJS 是一个强大的JavaScript应用程序框架,用于构建富客户端Web应用。路由(Routing)是现代Web应用中的关键概念,它允许用户通过URL与应用的不同部分进行交互。在ExtJS 6中,路由机制得到了改进,主要的配置和...
ExtJS3 升级到 ExtJS4 方案 ExtJS3 升级到 ExtJS4 需要修改大量代码,主要是因为 ExtJS4 配备了一类新的系统,不向后兼容...ExtJS3 升级到 ExtJS4 需要修改大量代码,需要我们重新学习和适应 ExtJS4 的新特性和变化。
### EXTJS 4 Web应用程序开发宝典 #### 知识点概述 《EXTJS 4 Web应用程序开发宝典》是一本全面介绍EXTJS 4框架的书籍,它为读者提供了丰富的资源来掌握这一强大的Web应用开发工具。EXTJS 4相较于其前一版本EXTJS ...
EXTJS in Action 是一本专为学习EXTJS编写的书籍,但这里我们主要关注学习笔记中的关键知识点。 首先,EXTJS的目录结构非常重要,因为它包含了所有必要的资源和源码: 1. `adapter`:这部分包含了适配器,用于将...