Created
May 13, 2011 15:34
-
-
Save Hyvi/970752 to your computer and use it in GitHub Desktop.
#QQ 云输入法 嵌入页面的 JS脚本# 其中第二行 使用了“!!q” 而不是直接使用 “q”
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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