JS知识点合集
JS知识点合集
作用域和作用域链
作用域
当函数在执行前,会创建函数执行期上下文对象,它定义了函数执行时的环境,我们将其理解为作用域。
一般作用域区分为
- 全局作用域
如在script标签中定义的变量,它可以在全局被访问,其所处的环境即全局作用域 - 函数/局部作用域
在函数内部定义的变量,不能在外部被访问到,其所处环境为函数作用域
作用域链
函数有一个scoped属性,存放着作用域的集合,该集合程链式结构,我们将其成为作用域链。
原型
函数的一个属性,定义了由构造函数实例化出的对象的公共祖先
function Person() {}
Person.prototype.height = 180;
var person = new Person();
// 可访问person .height
实例的__proto__属性指向了构造函数的原型。它们的关系如下
构造函数的原型属性Person.prototype
实例化对象、构造函数、原型的关系
原型存在一个属性constructor指向构造函数,同理实例化的对象也可以访问到这个属性
原型Person.prototype也有自己的原型
原型链的终点为null,原型组成的链状结构就是原型链,也就是这条蓝线
参考
由于原型的存在,实例可以访问到原型上的属性和方法,可用于实现继承
闭包
函数执行时,内部的函数被保存到了外部,从而使得函数执行期上下文(作用域)不被销毁,可以从外部访问到函数内部定义的变量。
由于闭包会使得函数的作用域不被释放,若使用不当会导致内存泄漏。
闭包的用途:
主要用途就两个:
1、将变量保存在内存中,不被销毁
私有化属性:
function onePerson() {
let name = "";
return {
setName(newName) {
name = newName
},
getName() {
return name;
}
}
}
const p1 = onePerson();
p1.setName("xiaoming");
p1.getName(); // xiaoming
累加器:
function Calculator() {
let num = 0;
return {
add() {
num++;
},
get() {
return num
}
}
}
const c1 = Calculator();
c1.add();
c1.get(); // 1
const c2 = Calculator();
c2.get(); // 0
2、模拟块级作用域
在 ES6 之前,是没有块级作用域的概念的,变量只有全局作用域和函数作用域。ES6 可以使用 let 关键字来实现块级作用域,变量的作用域在代码块中({})。
先写一个函数
function test1() {
for(var i = 0; i < 10; i++) {
setTimeout(() => {
console.log(i);
}, 0)
}
}
test1();
由于异步任务执行时变量i的值已经变成10了,最后执行结果是10个10
可以用es6的let,或者闭包
function test2() {
for(var i = 0; i < 10; i++) {
setTimeout((function (j) {
return () => console.log(j)
}(i)))
}
}
test2();
当然也可以这么写
function test2() {
for (var i = 0; i < 10; i++) {
(function (j) {
setTimeout(() => {
console.log(j);
}, 0)
}(i))
}
}
test2();
上一篇: Android详解之NoHttp最基本使用(无封装)
下一篇: 8.25重点内容