一文总结涵盖了JS的大部分注意点和难点。
一、JS的数据类型:一切皆对象。
值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。
引用数据类型:对象(Object)、数组(Array)、函数(Function)。
小马把对象理解为类似oop的class,可拥有属性和函数。

你可以使用以下语法创建对象方法:
methodName : function() { // 代码 }
json与JS对象的区别:

匿名函数 : nAdd=function(){n+=1} 。
以上函数实际上是一个 匿名函数 (函数没有名称)。
函数存储在变量中,不需要函数名称,通常通过变量名来调用。nAdd()
自调用函数:
函数表达式可以 "自调用"。
自调用表达式会自动调用。
如果表达式后面紧跟 () ,则会自动调用。
不能自调用声明的函数。
通过添加括号,来说明它是一个函数表达式:
(function () {
var x = "Hello!!"; // 我将调用自己
})();
以上函数实际上是一个 匿名自我调用的函数 (没有函数名)。
通俗理解为:
(function(){}()) 外面一个括号的是直接获取返回值;
里面计算一次
(functuon(){})() 外面2个括号并排的;
是先计算前面括号的值,然后执行这个返回值, 当然返回的肯定要是函数。
二、作用域
JavaScript 变量生命周期
JavaScript 变量生命周期在它声明时初始化。
局部变量在函数执行完毕后销毁。
全局变量在页面关闭后销毁。
函数参数只在函数内起作用,是局部变量。
如果变量在函数内没有声明(没有使用 var 关键字),该变量为全局变量。以下实例中 carName 在函数内,但是为全局变量。
变量的作用域无非就是两种:全局变量和局部变量。Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!
// 此处可调用 carName 变量
function myFunction() {
carName = "Volvo";
// 此处可调用 carName 变量
}
在 HTML 中, 全局变量是 window 对象: 所有数据变量都属于 window 对象。
//此处可使用 window.carName
function myFunction() { carName = "Volvo";}
三、变量提升
JavaScript 中,函数及变量的声明都将被提升到函数的最顶部。
JavaScript 中,变量可以在使用后声明,也就是变量可以先使用再声明。
四、this 关键字
面向对象语言中 this 表示当前对象的一个引用。
但在 JavaScript 中 this 不是固定不变的,它会随着执行环境的改变而改变。
在方法中,this 表示该方法所属的对象。
如果单独使用,this 表示全局对象。
在函数中,this 表示全局对象。
在函数中,在严格模式下,this 是未定义的(undefined)。
在事件中,this 表示接收事件的元素。
类似 call() 和 apply() 方法可以将 this 引用到任何对象。
var person = {
firstName: "John",
lastName : "Doe",
id : 5566,
fullName : function() { return this.firstName + " " + this.lastName; }
};
五、JavaScript let 和 const
ECMAScript 2015(ECMAScript 6)
ES2015(ES6) 新增加了两个重要的 JavaScript 关键字: let 和 const。
let 声明的变量只在 let 命令所在的代码块内有效。
const 声明一个只读的常量,一旦声明,常量的值就不能改变。
在 ES6 之前,JavaScript 只有两种作用域: 全局变量 与 函数内的局部变量。

六、闭包
JS的终极BOSS。
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

注意一下,这里如果不是自调用(如下),返回的会是啥??比较两个不同。

总结:定义在一个函数A内部的函数B,B函数对父级A函数的局部变量a进行操作+1,此时重复调用A,a将像一个全局变量一样存在内存中被累加计算。
以下来自这里,小马觉得比较通俗易懂。


在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。
为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。
这段代码中另一个值得注意的地方,就是"nAdd=function(){n+=1}"这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。
在js中,函数即闭包,只有函数才会产生作用域的概念。
使用闭包主要是为了设计私有的方法和变量,读取函数内部的变量,另一个就是让这些变量始终保持在内存中
闭包的优点是可以避免全局变量的污染,
缺点是闭包会常驻内存,增大内存使用量,使用不当很容易造成内存泄露和网页的性能问题, 解决方法是,在退出函数之前,将不使用的局部变量全部删除
标准的闭包用法有三个条件:
1.定义了内部函数(这里是f2)
2.内部函数引用了外部函数的变量(f2引用了n)
3.这个内部函数在其他地方被使用(return了f2,f2在外面被调用result)--想到上面的累加器自调用函数闭包。
网友评论