Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3-变量、作用域和内存问题 #7

Open
Ogurimuio opened this issue Feb 23, 2019 · 0 comments
Open

3-变量、作用域和内存问题 #7

Ogurimuio opened this issue Feb 23, 2019 · 0 comments
Assignees
Labels
JavaScript something about JavaScript 读书笔记 整理书籍知识点

Comments

@Ogurimuio
Copy link
Owner

变量、作用域和内存问题

变量类型:

  • 基本类型值:简单的数据段,(undefined、null、boolean、number、string,5个基本数据类型),按值访问,实际的值存在变量中,可直接操作实际的值。
  • 引用类型值:由多个值构成的对象,按引用访问,实际的对象存在内存中,不能直接操作,而只能操作对象的引用

变量的创建与属性

  • 基本类型值的变量没有属性
var name="assas"
name.age=27			//错误,name.age=undefined
  • 引用类型值的变量可以添加属性和方法
var person=new Object()
person.name="namedad"	//正确

变量的复制

  • 基本类型值

    复制后,两个变量完全独立,任何操作不会互相影响

var num1=5
var num2=num1		//num1=num2=5,且num1与num2完全独立
  • 引用类型值

    复制后,两者都指向堆中保存的同一个对象,操作在一个上,另一个也随之改变

var obj1=new Object()
var obj2=obj1		//obj2和obj1都指向内存(堆)中的同一个对象

obj.name="Nical"
alert(obj2.name)	//也改为"Nical"

函数参数的传递

参数只能够 按值传递

  • 基本类型值

    传递时,把被传递的值复制给一个局部变量(即函数的参数)

function addTen(num){	//这里的num是一个局部变量
	num+=10;		
	return num;
}

varcount=20;
var result=addTen(count)

//result=30,count=20;
  • 引用类型值

    虽然是按值传递,但依然会按引用来访问同一对象

function setName(obj){
	obj.name="Nical";		
	
	obj=new Object();
	obj.name="Grey"		//person.name依然是Nical,说明是按值传递,不是按引用传递
}

var person=new Object();
setName(obj)

//person.name="Nical";	//说明是按引用来访问

检查数据类型

使用typeof,或者instanceof

var o=new Object()
alert(typeof o);	//object
alert(o instanceof Object)	//变量o是Object类型吗? 返回true

执行环境及作用域

环境中定义的变量和函数都保存在该环境的变量对象中,直到该环境中所有代码执行完,该环境和变量对象才会被销毁

  • 全局执行环境:在web浏览器中通常是指**window对象*,全局变量环境直到程序退出(关闭网页)时才会被销毁。

  • 作用域链:保证对执行环境有权访问的所有变量和函数的有序访问。

    • 作用域前端:当前所在环境的变量对象。

      如当前环境是个函数,则变量对象最开始时,只有函数的arguments

    • 作用域的下一个变量对象:来自(包含)外部环境。

      (一直延续到全局执行环境)

    • 作用域的最后一个对象:全局执行环境的变量对象。

var color="blue"

function changeColor(){
	var another="red"

	function swapColor(){
		var temp=another
		another=color;
		color=temp
		//这里可以访问color,temp,another
	}
	//这里可以访问color,another。但不能访问temp
	swapColor()
	
}
//这里只能color
changeColor()

延长作用域链

使用以下语句时,可以延长。

(在作用域链的前端临时添加一个变量对象,并在代码执行后移除)

  • try-catch语句中的catch块
  • with语句
function build(){
	var qs="111"

	with(location){		//因此可以包含location对象的所有属性和方法
		var url=href+qs;	//可以引用location.href
	}
	return url;  //因为在with中被定义,所以可以引用
}

js没有块级作用域

比如,在 if和for 中创建的变量,在花括号外部依然可以使用,而不会跟着if和for的结束而被销毁

  • 在声明变量时,如果没有写var关键字,则会将该变量加入到全局变量中。

  • 搜索变量的过程:从作用域链前端开始,向上搜索,直到全局变量。

    如果过程中有同名变量,则会定位在第一个找到的那个变量。

    var color="blue"
    
    function getColor(){
    	var color="red"
    	alert(color)	//red
    	return color
    }
    alert(getColor()) //red

垃圾收集

js有自动垃圾收集机制。

垃圾收集器周期性执行:找出不再使用的变量——》释放内存。

局部变量只在函数执行过程中存在。

垃圾收集器需要跟踪变量,在不需要再用的变量上打标记。

标记收集的方法:

  • 标记清除

    变量进入环境——标记为 “进入环境”,不会被释放。

    变量离开环境——标记为**“离开环境”**

    运行时:为所有变量加上标记

    接着:**去掉 **目前环境中的变量和被环境引用的变量 的标记。

    在此之后,再被加上标记的变量——就是准备删除的变量。

    (因为环境以无法访问到这些变量了)

  • 引用计数

    跟踪每个值被引用的次数。

    1:声明时,引用次数为1

    +1:值被赋值给另一个变量时。

    -1:某个变量原先引用该值,后来被赋值了另一个值时。

    0:将被清除

    (注意,该方法可能引起内存泄漏。比如,两个object的某个属性互相引用,形成循环,则永远不会被清楚。可以通过手动设置这两个属性为null来解决。)

    var obj1=new Object()
    var obj2=new Object()
    
    obj1.someObj=obj2
    obj2.anotherObj=obj1	//循环引用,两个obj的次数都为2

垃圾收集器的周期时间间隔,会影响性能问题。

可以使用以下方法立即执行垃圾收集:

  • window.CollectGarbage()
  • window.opera.collect()

管理内存

尽量确保占有最少的内存,使页面获得更好的性能。

代码中只保存必要的数据。一旦数据不用,就设置其为null,来释放引用——这就叫解除引用,适用于大多数全局变量/对象。

  • 局部变量会在 离开执行环境时被自动解除引用
  • 全局变量需要我们手动解除引用)

解除引用:对消除循环和垃圾收集都有好处。

@Ogurimuio Ogurimuio added the JavaScript something about JavaScript label Feb 23, 2019
@Ogurimuio Ogurimuio self-assigned this Feb 23, 2019
@Ogurimuio Ogurimuio added the 读书笔记 整理书籍知识点 label Feb 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
JavaScript something about JavaScript 读书笔记 整理书籍知识点
Projects
None yet
Development

No branches or pull requests

1 participant