Skip to content

Instantly share code, notes, and snippets.

@Hyvi
Created May 13, 2011 15:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Hyvi/970752 to your computer and use it in GitHub Desktop.
Save Hyvi/970752 to your computer and use it in GitHub Desktop.
#QQ 云输入法 嵌入页面的 JS脚本# 其中第二行 使用了“!!q” 而不是直接使用 “q”
(function(q){
!!q?q.toggle():
(function(d,j){
j=d.createElement('script');
j.src='//ime.qq.com/fcgi-bin/getjs';
j.setAttribute('ime-cfg','lt=2');
d.getElementsByTagName('head')[0].appendChild(j)
}
)
(document)}
)
(window.QQWebIME)
// 由该问题 引申出来的 两个 知识点
// 1, zhihu.com 上: Javascript 中的 this 如何理解?
//===============================================
//这个不仅是this的作用域,还涉及到function和 new function的区别
var a=10;
function test(){
a=5;
alert(a);
alert(this.a);
var a;
alert(this.a);
alert(a);
}
//问:执行test()和new test() 返回值分别为啥?
//答:返回结果,alert的内容:
//test(): 5,10,10,5
//new test():5,undefined,undefined,5
//解释下:
//在第一种情况 this指拥有test的对象,这儿是windows
//第二种情况this指new创建的对象,因为未定义this.a,所以undefined
//闭包 作用域 上下文 http://mzhou.me/?p=81001
//作用域
//表示变量或函数起作用的区域,指代了它们在什么上下文中执行。Javascript总作用域一共有两种:全局作用域和本地作用域。
//在Javascript中本地作用域是按照函数来区分的。
var global = "11"; //全局作用域
function fun() {
var local = "22";//本地作用域1
}
function fun2() {
var local2 = "22";//本地作用域2
for (var i=0;i<100;i++) {
//本地作用域2
}
}
/**
不象Java语言那样for循环也是一个作用域,在Javascript中本地作用域是按照函数来区分的。
Javascript的作用域概念类似词法作用域。
词法作用域:也叫做静态作用域,变量的作用域是在定义时决定而不是执行时决定。即词法作用域取决于源码,通过静态分析就能确定。
*/
/**
作用域链
与“原型链”类似,Javascript的作用域链也是按有顺序查询的。在访问变量时,先查看本地作用域是否有此变量,
如果没有则依次向上一级作用域查找直到全局作用域。如果全局作用域也没有此变量,那么将会在全局作用域中声明这个变量。如下的代码:
*/
function f() {
name = "global";
var local = "local";
}
f();
console.log(name); //global
console.log(local);//undefine
//name变量被声明在全局作用域。
/**
上下文
又可以理解为上下文对象,表示当前代码执行时所处的环境。即是this变量所指代的对象;这么理解比较困难,直接看个例子:
*/
function Test() {
console.log(this);
}
Test(); //window
new Test();//Object
/**
在执行Test()时,此时的上下文对象是window,即Javascript的全局对象!
在执行new Test();时新建了一个Object,此时执行Test函数的上下文对象就是Object。
如果还不理解,可以看我的如何用Javascript实现面向对象编程一文中有一段代码如下:
*/
function newObj(Fun,arguments) {
var o = {};
if (Fun && typeof Fun === "function") {
o.__proto__ = Fun.prototype;
Fun.apply(o, arguments);
return o;
}
}
/**
这主要是new函数操作的模拟,可以看到Fun.apply(o,arguments);
这一步,apply的作用是指定执行Fun函数并制定其上下文为o,输入参数为arguments对象。
所以new Test()得到的结果是Object。
*/
/**
闭包
表示能访问和操作其他内部作用域的变量的表达式(通常是函数)。
用简单的语言描述就是:能操作其他本地作用域变量的函数就是闭包。还是看代码:
*/
function fun() {
var i = 1;
return function() {
i++;
console.log(i);
}
}
var closure = fun();
closure(); //2
closure(); //3
/**
请先按Java语言或其他非闭包语言的逻辑思考。
当fun函数执行完毕时,其内部变量i应该会被释放,当closure函数再此执行并调用i时输出错误(因为i未被声明)。
但是在Javascript中却打印出了值,这一切都归功于闭包。
在执行fun()函数时,闭包就被创建。此时i并没有被释放,closure依然可以被访问到。
另外注意闭包的本质是表达式(通常是函数),所以闭包是在函数生成时定义的。(上面代码的第3行定义闭包)!
*/
/**
闭包的作用
闭包最大的作用就是来阻止外部程序随意访问内部变量,只能通过提供的接口来访问和操作。如下面一个记数器的实现:
*/
var counter = (function() {
var i=0;
return {
add:function() {
i++;
return this;
},
get:function() {
return i;
}
}
})();
counter.add().add().add();
console.log(counter.get()); //3
//如果不用闭包直接暴露变量,那就会出现如下的情况产生bug:
i=0;
function add() {
i++;
}
add();
add();
i+="1";
add();
console.log(i);//22
//至于为什么产生这么奇怪的结果就要归功与+=和++这两个操作符了。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment