小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
原始值与引用值
- ECMAScript变量可以包含两种不同类型的数据:原始值和引用值。原始值就是最简单的数据,引用值则是由多个值构成的对象
动态属性
//引用值
let person = new Object()
person.name = "hello"
console.log(person.name) //hello
//原生值
let name = "hello"
name.age = 20
console.log(name.age) //undefiend
原始类型的初始化可以使用原始字面量形式。如果使用new关键字,则会创建一个Object类型的实例,但其行为类似原始值
let name1 = "hello"
let name2 = new String("name2")
name1.age = 20
name2.age = 20
console.log(name1.age) //undefiend
console.log(name2.age) //20
console.log(typeof name1) //String
console.log(typeof name2) //Object
复制值
- 原始值复制,复制后的值与复制前的值是两个值,互不干扰
let num = 5
let num2 = num
- 引用值复制,复制的值实际上是一个指针,指向堆内存中的对象
let obj1 = new Object()
let obj2 = obj1
obj1.name = "hello"
console.log(obj2.name) //"hello"
erDiagram
Object ||--|{ obj1 : Object
Object ||--|{ obj2 : Object
传递参数
- 按值传递参数,值会被复制到一个局部变量
function add(num){
num += 10
return num
}
let count = 20
let result = add(count)
console.log(count); //20没有变化
console.log(result); //30
- 按引用传递,值在内存的位置会被保存到一个局部变量,本地变量的修改会反映到函数外部
function setName(obj){
obj.name = "hello"
}
let result = new Object()
setName(result)
console.log(result.name); //hello
执行上下文与作用域
- 上下文代码在执行的时候,会创建一个作用域链,决定了访问变量和函数时的顺序
var color = "blue";
function chang() {
if (color === "blue") {
color = "red";
} else {
color = "blue";
}
}
chang()
函数chang()的作用域包含两对象,一个是自己的变量对象(arguments),还有一个就是全局上下文变量对象,函数内部可以访问color,就是因为可以在作用域链中找到它
- 局部作用域中定义的变量可以在局部上下文中替换全局变量
var color = "blue";
function chang() {
let herColor = "red";
function Colors() {
let tem = "antColor";
herColor = color;
color = tem;
//这里可以访问color, herColor,tem
}
//这里可以访问color, herColor,访问不到tem
Colors()
}
//这里可以访问color
chang();
总结
- 执行上下文分全局上下文,函数上下文,块级上下文
- 代码每进入一个新上下文,都会创建一个作用域,用于搜索变量和函数
- 函数或块可以访问自己的作用域内的变量,还能访问全局的
- 全局上下文只能访问自己的