作用域
作用域简单的说就是函数和变量的可访问范围
作用域其实就分为两种,一种是全局作用域,一种是局部作用域
写在最外边的就是全局作用域
例:
var arr = "123";
function(){
}
写在代码片段里面的就是局部作用域
例:
function(){
var arr = "123";
}
但是写在代码片段里面未使用var声明的也是全局作用域
例:
function(){
arr = "123";
}
作用域链
作用域链就是保证在一定的执行环境中有权访问的变量和函数的有序访问
逐级向上搜索的作用域链,一直延续到全局执行环境,全局环境也是作用域最后一个可访问的对象
函数的提前声明
也就是声明提前,在执行js引擎之前的 “ 预编译 ”时进行的,执行在代码运行之前
例:
var scope = "glocal";
function f(){
console.log(scope); //输出"undefined",而不是"global"
var scope = "local"; //变量在这里赋初始值,但变量本身在函数体内任何地方
均是有定义的
console.log(scope);//输出"local"
}
闭包
闭包就是一个封闭的函数,当一个函数被外部函数之外的变量引用时就行成了闭包
闭包的作用:
第一个就是可以读取自身函数外部的变量且内部变量不会别外部引用
当闭包被引用后就可以随意修改内部变量
第二个就是私有变量和私有方法,将对变量(状态)的变化封装在安全的环境中
第三个就是让这些外部变量始终保存在内存中但是不合理的使用会造成内存的泄露和性能消耗。
例:
var dd = function (){
var str = "123";
return {
getstr:function(){
return str;
},
setstr:function(newstr){
str = newstr;
}
}
}
var foo = new dd();
foo.setstr("456"); //改变闭包里的str的值
console.log(foo.getstr()); //456 获取改变后的str的值
JavaScript 闭包与类(原型链)之间的开发方式
原型链是共享属性和方法,是可以实现继承的,当调用对象添加的方法跟原型链重复时,
原型方法会被替换 (原型链上的指向同一内存地址)
闭包是对属性和方法的封装,可以延迟使用外部变量和方法,
当闭包被引用后可以随意修改闭包内的属性和方法(每个引用者都会开辟一个内存地址)
构造函数和普通函数的区别
function Person(){
this.name = "Jack"; // 把name属性添加到了window对象上面
alert(this === window); //如果不作为构造方法调用,则是true
}
Person(); // 把构造函数当做普通方法调用。这个时候内部的this指向了window
alert(window.name); //Jack
function Human(){
this.name = "Mark";
alert(this instanceof window); // false
alert(this instanceof Human); //true
}
var h = new Human(); //当做构造函数来调用,创建一个对象
alert(h.name);
1 构造函数像普通函数调用时this其实指向了window对象
2 如果用new的方式使用就是构造函数,this指向调用者
3 一般构造函数首字母大写
面向对象
以下是个人对面向对象的理解
每个事物都可以看做一个对象
特性一:封装
也就是把客观事物封装成抽象的类或具体的对象,
并且类或对象可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
特性二:继承
可以让某个类型的对象获得另一个类型的对象的属性的方法
优点:
低耦合,保护命名空间,复用性高
是将松散的JS代码进行整合,便于后期的维护
是让我们的代码适应更多的业务逻辑。
面向对象中的“对象”是指问题空间中的元素(猫、狗)及其在解空间中的表示
(new Cat(); new Dog())。对象是过程(函数)与数据的结合。
对象与闭包
对象是在数据中以方法的形式内含了过程,闭包是在过程中以环境的形式内含了数据。
所谓“闭包是穷人的对象”、“对象是穷人的闭包”,就是说使用其中的一种方式
,就能实现另一种方式能够实现的功能。
基本类型的值和引用类型的值
基本类型是简单的数据段
引用类型是由多个属性构成的对象,存在内存中(堆),操作对象时操作的是引用而不是直接操作对象
基本类型:
var num1 = 5;
var num2 = num1;
引用类型:
var obj1 = new Object();
var obj2 = obj1;
obj1.name = “jon”;
console.log(" obj2.name ") // jon
垃圾回收
垃圾回收机制回收的是局部变量,它是周期性运动的,可以手动启动,
通过标记清除方法可以将不被回收的垃圾及时清理
例1:
function a(){
var num = 10;
return function(){
num ++;
console.log(num);
}
}
a()(); //11
a()(); //11
没有别第三方引用执行过程中产生的数据会被回收
例2:
function a(){
var b = 0;
return function(){
b ++;
console.log(b)
}
}
var d = a();
// console.log(a());
d();//1
d();//2
d();//3
b被外部函数a之外的变量引用了,执行过程中产生的数据不会被回收
例2中如果想清楚b的全局变量可以这样做
function a(){
var b = 0;
return function(){
b ++;
console.log(b);
b = null;
}
}
var d = a();
// console.log(a());
d();//1
d();//1
d();//1
执行上下文
执行上下文可以理解为一片内存区域,每次执行函数都会产生一个新的执行上下文,
随即产生新的内存区域,内存中的变量等构成了执行上下文
网友评论