javascript 变量、作用域、命名空间、this
javascript变量主要分为两类:
I. 全局变量
II. 局部变量(函数内的变量)
全局变量就是在当前页面起作用, 一个页面当中的iframe也不管用, 只在一个页面当中有效。
如果JS代码很多的时候, 我们都要引用JS脚本文件, 但是有可能出现两个脚本当中的全局变量名是一样的, 这会出现错误。 因为面对这些问题JS不会报错,
所以我们需要使用命名空间来解决这些冲突。
<pre name="code" class="html">function myFunc() {
var x = 5;
};
console.log(x); //undefined
<pre name="code" class="html">function myFunc() {
x = 5;
});
console.log(x); //5 x是全局作用域 在 window 下
<pre name="code" class="html"><pre name="code" class="html"><pre name="code" class="html">具体看一下 jQuery一类的函数库
(function() {
var jQuery = { /* all my methods go here */ };
window.jQuery = jQuery.
})();
说明:这些变量函数什么的仍然存在于本地作用域,所以不能从外面直接访问,当然,要访问的话,只能通过这个唯一的全局的接口:jQuery,这就是所谓的闭包的最大功德
下面看2个小示例
<pre name="code" class="html">function outer() {
var x = 5;
function inner() {
console.log(x); //5 本地作用域以函数为单位,所以在一个函数内定义的函数,是可以访问外面这个包含它的函数的本地变量的
}
inner();
}
<pre name="code" class="html">function outer() {
var x = 5;
function inner() {
console.log(x); //5
var y = 10;
}
inner();
console.log(y); //undefined outer()函数并不能访问inner()里面的任何变量
}
下面说下this 这个东东
function foo() {
console.log(this); //global object 译者注:其实就是window
};
app = {};
app.foo = function() {
console.log(this); //points to app object
}
var link = document.getElementById(myId);
link.addEventListener(click, function() {
console.log(this); //points to link
}, false);
上面的 this 相信大家都能看明白 接下来看看下面这段代码
<div class="container"><pre name="code" class="html">$(myLink).on(click, function() {
console.log(this); //points to myLink (as expected)
var _this = this; //store reference
$.ajax({
//ajax set up
success: function() {
console.log(this); //points to the global object. Huh?
console.log(_this); //better!
}
});
});
关于“var _this = this;”这一句的用意的疑问 ? 我解释一下
<a>$(#myLink).on(click, function() {})这句的意图是当这个DOM元素被点击时,这个函数便被执行</a>
<a>可是由于这个函数是作为一个事件处理器被呼叫的,所以this变量会指向ID为myLink的DOM元素</a>
<a>而你在Ajax请求里指定的success方法只是一个常规的函数,所以当它被执行的时候,this被赋值为全局对象</a>
你总会见到有人写:var _this = this或者var that = this,或者类似的东西
这样做的目的是把当前this的值备份留作以后不时之需
下面看几道 小试题
function test() { // a scope
for(var i = 0; i < 10; i++) { // not a scope
// count
}
console.log(i); // 10
}
// global scope var foo = 42; function test() { // local scope foo = 21; } test(); foo; // 21 <pre name="code" class="html">Javascript 中局部变量只可以通过两个方式产生,一是通过关键字 var 来声明,一是作为函数的形参。 // global scope var foo = 1; var bar = 2; var i = 2; function test(i) { // local scope of the function test i = 5; var foo = 3; bar = 4; } test(10); //函数 <code>test</code> 内部的变量 <code>i</code> 和 <code>foo</code> 是局部变量,而 <code>bar</code> 则会覆盖外部的全局变量 <code>bar</code>。 总结 ; <h2>名称解析顺序</h2><p>当尝试在一个函数作用域内访问一个 <code>foo</code> 变量时,<code>Javascript</code> 将会按照下面的顺序查找:</p><ol><li>当前作用域内是否有 <code>var foo</code> 的定义。</li><li>函数形参中是否有 <code>foo</code> 变量。</li><li>函数自身的名称是否为 <code>foo</code>。</li><li>跳到外层定义域,再从第一部开始查找起。</li></ol><p> </p><p> </p><p> </p><p>建议大家使用匿名的外部函数来将代码封装到空间内,这样不仅可以解决命名空间的冲突,同时也有利于程序的模块化。 此外,使用全局变量不是一个好习惯,这将带来高成本的维护代价而且容易产生错误 </p>