未加星标

JavaScript的作用域

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二03 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏
javascript的作用域

昨天来源:cnblogs

什么是作用域

让我们从全局作用域开始。从你开始写JavaScript的第一刻起,你的代码就处于全局作用域下。全局作用域可以从任何地方访问。除此之外你可以在全局作用域下通过函数创建更小的作用域。局部作用域无法从全局作用域访问,只能从相同作用域(或者叫函数)访问。全局作用域可以从任何地方访问!

全局作用域

当一些东西没有定义在一个函数中时他就被定义在了全局作用域下。只在一个JavaScript文件中定义一些变量,他们就在全局作用域中。

JavaScript 例子

var myGlobalScope = 'Global scope value'; console.log('myGlobalScope: ' + myGlobalScope); // "myGlobalScope: Global scope value" 局部作用域

局部作用域通过一个函数创建。其中定义的任何东西都只能在其内部访问,或者它的子作用域(在那个函数内的函数)。在一个局部作用域中,你可以访问全局作用域或者父级作用域(父级函数)!

JavaScript 例子

var myGlobalScope = 'Global scope value'; function myLocalScopeFunction { var myLocalScope = 'myLocalScope value'; console.log('----- start of local scope in function -----'); console.log('myGlobalScope: ' + myGlobalScope); console.log('myLocalScope: ' + myLocalScope); console.log('----- end of local scope -----'); } myLocalScopeFunction; console.log('----- start of Global scope in function -----'); console.log(log(log('----- end of Global scope -----');

Console输出的结果:

"----- start of local scope in function -----" "myGlobalScope: Global scope value" "myLocalScope: myLocalScope value" "----- end of local scope -----" "----- start of Global scope in function -----" "myGlobalScope: Global scope value" "ReferenceError: myLocalScope is not defined at domigov.js:15:57 at https://static.jsbin.com/js/prod/runner-3.39.15.min.js:1:13926 at https://static.jsbin.com/js/prod/runner-3.39.15.min.js:1:10855"

这个例子中,正如你上面看到的当你试图在全局作用域下获取定义在子作用域中的变量时将会报错。

为什么在JavaScript中使用作用域?

在JavaScript中,你可以在不同作用域中使用相同的变量名定义变量,它不会被重写。如果你想改变变量的值只需要直接改变而不用重新定义一遍。

不重写

(function { var var1 = 'variable 1 value in parent scope'; (function { // Scope 1 var var1 = 'variable 1 value in scope 1'; console.log('scope 1: ' + var1); // Is 'variable 1 value in scope 1' }); (function { // Scope 2 var var1 = 'variable 1 value in scope 2'; console.log('scope 2: ' + var1); // Is 'variable 1 value in scope 2' }); console.log('Parent scope: ' + var1); // Is 'variable 1 value in parent scope' });

Console输出的结果:

"scope 1: variable 1 value in scope 1" "scope 2: variable 1 value in scope 2" "Parent scope: variable 1 value in parent scope"

重写

(function { var var1 = 'variable 1 value in parent scope'; (function { // Scope 1 var1 = 'variable 1 value in scope 1'; console.log('scope 1: ' + var1); // Is 'variable 1 value in scope 1' }); (function { // Scope 2 var1 = 'variable 1 value in scope 2'; console.log('scope 2: ' + var1); // Is 'variable 1 value in scope 2' }); console.log('Parent scope: ' + var1); // Is 'variable 1 value in parent scope' }); console.log('Global scope: ' + var1); // Is undefined

Console输出的结果:

"scope 1: variable 1 value in scope 1" "scope 2: variable 1 value in scope 2" "Parent scope: variable 1 value in scope 2" "ReferenceError: var1 is not defined at zodaqo.js:19:57 at https://static.jsbin.com/js/prod/runner-3.39.15.min.js:1:13926 at https://static.jsbin.com/js/prod/runner-3.39.15.min.js:1:10855"

如果你想防止自己不小心在不同作用域改变变量的值,只需要在函数体开始部分声明你的变量。

变量提升

这也被称作变量提升。它将防止你在意外情况下重写你的变量。(注:个人理解作者这里写的变量提升并不是我们平时说的变量提升的现象,简单地理解成手动提前声明变量就好。)

变量提升例子

// Global scope (function { // Parent scope var var1, var2, var3; var1 = 'variable 1 value in parent scope'; var2 = 'variable 2 value in parent scope'; var3 = 'variable 3 value in parent scope'; (function { var var1, var2, var3; // Scope 1 var1 = 'variable 1 value in scope 1'; var2 = 'variable 2 value in scope 1'; var3 = 'variable 3 value in scope 1'; console.log('scope 1: ' + var1); console.log('scope 1: ' + var2); console.log('scope 1: ' + var3); }); console.log('Parent scope: ' + var1); console.log('Parent scope: ' + var2); console.log('Parent scope: ' + var3); });

Console输出的结果:

"scope 1: variable 1 value in scope 1" "scope 1: variable 2 value in scope 1" "scope 1: variable 3 value in scope 1" "Parent scope: variable 1 value in parent scope" "Parent scope: variable 2 value in parent scope" "Parent scope: variable 3 value in parent scope"

当然,如果这真是你的代码,你永远都不需要这么做。但是假如你正在写一个更大规模的JavaScript应用,非常推荐这么做!

然而,一些有经验的开发者出于一些原因不赞成这么做。但根据我的经验,它能防止很多问题!

私有 & 公有

使用过其他库或框架并且看过它们源码的开发者知道有些方法你可以在你自己的代码中使用,但是这些方法内部更小的函数则不能使用或访问。

这是因为存在私有和公有函数(属性)。公有函数可以从其他作用域访问到。私有函数只能从相同作用域访问,因此它对于其他作用域或父作用域是隐藏的。

公有和私有函数被用作JavaScript模块。一个模块很容易创建,只需通过一个"立即执行函数表达式"定义变量。这些模块可以在你的JavaScript任何地方使用。如果你想了解更多模块模式相关内容,转向Todd Motto的“精通模块模式”这篇文章!

JavaScript模块

var JavaScriptModule = (function { var javascriptModuleObject, privateFunction; privateFunction = function { return 'privateFunction is called!'; }; javascriptModuleObject = { methodOne: function { return 'methodOne is called!'; }, methodTwo: function { return 'methodTwo is called!'; } }; return javascriptModuleObject; }); 私有函数

当创建一个模块后我们现在可以发现私有和公有的区别。如果我们尝试获取私有函数将会报错。

var JavaScriptModule = (function { var javascriptModuleObject, privateFunction; privateFunction = function { return 'privateFunction is called!'; }; javascriptModuleObject = { methodOne: function { return 'methodOne is called!'; }, methodTwo: function { console.log(privateFunction); return 'methodTwo is called!'; } }; return javascriptModuleObject; }); console.log(JavaScriptModule.privateFunction);

Console输出的结果:

"TypeError: JavaScriptModule.privateFunction is not a function at dowazit.js:23:55 at https://static.jsbin.com/js/prod/runner-3.39.15.min.js:1:13926 at https://static.jsbin.com/js/prod/runner-3.39.15.min.js:1:10855"

这个函数只有模块内部可以访问。无法从外部访问!因此私有函数对内部逻辑比如复杂的计算,错误处理等等非常有用。

公有函数

对于我们的模块,公有函数(也叫方法)可以从模块外部获取。

var JavaScriptModule = (function { var javascriptModuleObject, privateFunction; privateFunction = function { return 'privateFunction is called!'; }; javascriptModuleObject = { methodOne: function { return 'methodOne is called!'; }, methodTwo: function { console.log(privateFunction); return 'methodTwo is called!'; } }; return javascriptModuleObject; }); console.log(JavaScriptModule.methodOne); console.log(JavaScriptModule.methodTwo);

Console输出的结果:

"methodOne is called!" "privateFunction is called!" "methodTwo is called!"

公有函数可以在你的模块外执行。例如你以Google Maps API为例。它是指全部公有和私有方法的集合。

var map; functioninitMap { map = new google.maps.Map(document.getElementById('map'), { center: {lat: -34.397, lng: 150.644}, zoom: 8 }); } Map方法是一个公有函数!这个公有函数执行了许多私有函数。所以你只需要调用一个函数然后它将帮你处理好剩下的事情!如何创建私有和公有函数如果你看了样例模块会发现它很简单!如果一个函数被返回了就将变为公有的。否则,它会保持私有!在模块中存在javascriptModuleObject对象,这个对象通过return语句被返回。

所以如果我们想让其它函数也变成公有的我们只要将它添加到这个对象上就可以了。我们可以将这个函数添加到对象内,也可以这样

javascriptModuleObject.newPublicFunction = function {}

大多数情况下我喜欢这样创建我得模块:

var JavaScriptModule = (function { var javascriptModuleObject, privateFunction; privateFunction = function { return 'privateFunction is called!'; }; javascriptModuleObject = {}; javascriptModuleObject.newPublicFunction = function { return 'new public functions!'; }; javascriptModuleObject.methodOne = function { return 'methodOne is called!'; }; javascriptModuleObject.methodTwo = function { console.log(privateFunction); return 'methodTwo is called!'; }; return javascriptModuleObject; }); console.log(JavaScriptModule.methodOne); console.log(JavaScriptModule.methodTwo); console.log(JavaScriptModule.newPublicFunction);

Console输出的结果:

"methodOne is called!" "privateFunction is called!" "methodTwo is called!" "new public functions!"

这样创建它是因为对哪个函数是公有或私有的可读性非常好。看一眼你就能发现所有绑定在对象上(会被返回)的函数都将成为公有的,剩下的将成为私有的!

总结

我希望你对JavaScript中的作用域有了更好的理解并且知道通过它能做什么和如何在你自己的代码中实现它!如果没有,请在评论区提问!我很乐意帮你理解它!

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

主题: JavaScriptJava变量乐购
分页:12
转载请注明
本文标题:JavaScript的作用域
本站链接:http://www.codesec.net/view/480155.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(37)