作用域决定了你的代码里的变量和其他资源在各个区域中的可见性。
优点:
为代码提供了一个安全层级,用户只能访问他们当前需要的东西
提升性能,比如变量访问速度,跟踪 bug 并减少 bug
解决不同范围的同名变量命名问题
在 JavaScript 中有两种作用域:
全局作用域:定义在函数之外的变量会被保存在全局作用域中
局部作用域(函数作用域):当变量定义在一个函数中时,变量就在局部作用域中,每个函数在调用的时候会创建一个新的作用域。作用域是在函数被创建的时候就定义的?
ECMAScript 6 引入了let和const关键字。这些关键字可以代替var。
let likes = ‘Coding‘;
const skills = ‘Javascript and PHP‘;
和var关键字不同,let和const关键字支持在块级声明中创建使用局部作用域。
if (true) { var name = ‘Hammad‘; let likes = ‘Coding‘;、 const skills = ‘JavaScript and PHP‘; } console.log(name); // logs ‘Hammad‘ console.log(likes); // Uncaught ReferenceError: likes is not defined console.log(skills); // Uncaught ReferenceError: skills is not defined
一个应用中全局作用域的生存周期与该应用相同。局部作用域只在该函数调用执行期间存在。
上下文指的是在相同的作用域中的this的值。可以使用函数方法改变上下文,执行的时候确定的。
在全局作用域中,上下文总是 Window 对象。
作为一个对象的方法,上下文就是这个方法所在的那个对象。
使用new关键字调用函数时上下文,上下文会设置为被调用的函数的实例
当在严格模式(strict mode)中调用函数时,上下文默认是 undefined。查资料
第一阶段是创建阶段,是函数刚被调用但代码并未执行的时候。创建阶段主要发生了 3 件事。
创建变量对象
创建作用域链
设置上下文(this)的值
第二个阶段就是代码执行阶段,进行其他赋值操作并且代码最终被执行。
词法作用域(静态作用域)的意思是在函数嵌套中,内层函数可以访问父级作用域的变量等资源,在定义时就确定。
当内部函数试着访问外部函数的作用域链(词法作用域之外的变量)时产生闭包。闭包包括它们自己的作用域链、父级作用域链和全局作用域。
闭包不仅能访问外部函数的变量,也能访问外部函数的参数。
即使函数已经return,闭包仍然能访问外部函数的变量。这意味着return的函数允许持续访问外部函数的所有资源。
当你的外部函数return一个内部函数,调用外部函数时return的函数并不会被调用。你必须先用一个单独的变量保存外部函数的调用,然后将这个变量当做函数来调用。
用闭包实现共有作用域和私有作用域:
(function () { // private scope })();
函数结尾的括号告诉解析器立即执行此函数。我们可以在其中加入变量和函数,外部无法访问。但如果我们想在外部访问它们,也就是说我们希望它们一部分是公开的,一部分是私有的。我们可以使用闭包的一种形式,称为模块模式(Module Pattern),它允许我们用一个对象中的公有作用域和私有作用域来划分函数。
var Module = (function() { function privateMethod() { // do something } return { publicMethod: function() { // can call privateMethod(); } }; })(); Module.publicMethod(); // works Module.privateMethod(); // Uncaught ReferenceError: privateMethod is not defined
Module 的return语句包含了我们的公共函数。私有函数并没有被return。函数没有被return确保了它们在 Module 命名空间无法访问。但我们的共有函数可以访问我们的私有函数,方便它们使用有用的函数、AJAX 调用或其他东西。
一种习惯是以下划线作为开始命名私有函数,并返回包含共有函数的匿名对象。这使它们在很长的对象中很容易被管理。向下面这样:
var Module = (function () { function _privateMethod() { // do something } function publicMethod() { // do something } return { publicMethod: publicMethod, } })();
另一种形式的闭包是立即执行函数表达式(Immediately-Invoked Function Expression,IIFE)。这是一种在 window 上下文中自调用的匿名函数,也就是说this的值是window。它暴露了一个单一全局接口用来交互。如下所示:
(function(window) { // do anything })(this);
Call 和 Apply 函数来改变函数调用时的上下文。
context={a:1,y:2};
function hello(a,b) {
alert(this.a);
alert(a);
alert(b);
}
hello();
hello.call(context,"cc","dd"); //1,cc,dd
hello.apply(context,["cc","dd"]); //
Bind 并不是自己调用函数,它只是在函数调用之前绑定上下文和其他参数。
(function introduce(name, interest) { console.log(‘Hi! I‘m ‘+ name +‘ and I like ‘+ interest +‘.‘); console.log(‘The value of this is ‘+ this +‘.‘) }).bind(window, ‘Hammad‘, ‘Cosmology‘)();
原文:https://www.cnblogs.com/yaoyao-sun/p/10365422.html