你真的了解变量吗?
Posted _小许_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了你真的了解变量吗?相关的知识,希望对你有一定的参考价值。
变量是编程语言中最基本的术语,用来代指计算机中存放的可变数据——如整数、小数、字符或被调用的一片内存空间。
变量可以保存不同的变量类型,比如整型、布尔型、对象、数组等等,每一个变量在内存中对应着一个内存地址,但是如果一个变量保存一个原始数据类型(整型、布尔型、字符串)则该变量的值是保存在栈内存中,而相对于那些较复杂的数据类型(数组、对象)则是在栈中只存储了一个固定长度的地址,这个地址指向堆内存中的值。这是由于栈和堆的两种数据结构的性质决定的。
对变量的使用一般包括变量的定义,变量的调用,变量的值传递,变量的销毁与内存释放。
变量可以时任何数据类型,数字,字符字符串,方法,对象等。变量的定义归结于不同语言的语法,如:
//java
//简单数据类型
String name = "_小许_";
String name = null;
int age = 21;
boolean flag = true;
//复杂数据类型对象
class Person
String name;
Integer age;
Person person1 = new Person();
# python
a = 10
b = "_小许_"
# 函数变量
def showName:
print("_小许_")
# 对象变量
class Person:
def __init__():
print("_小许_")
Person.__init__()
// go
var x int =10
y := "_小许_"
const name = "_小许_"
//结构体变量
type Person struct
name string
age int
变量的销毁都有语言的编译器或者解析器的GC来完成。
变量的传递是变量的核心,变量定义出来就是为了传递到不同的方法中实现不同操作,最终的得到用户需要的结果。
变量的传递包括值传递和引用传递,这也是和语言的特性息息相关,值传递是浅传递,引用传递是深传递。前者是简单的值拷贝,后者是内存地址的在此引用,一般通过修改指针变量来完成。
变量传递的途径,变量一般包含局部变量和全局变量,变量最终都通过IO输出并在内存中被销毁,因此变量只有在编译时在有意义。
笼统的说,在程序中对变量实现附加操作的主体就是方法,算数运算,逻辑运算等这些一般也依附于方法。无论是面向对象语言还是面向过程语言。
例如,在面向过程语言c语言中:
#include <stdio.h>
int sum()
int i, sum=0;
for(i=1; i<=100; i++)
sum+=i;
return sum;
int main()
int a = sum();
printf("The sum is %d\\n", a);
return 0;
//java
public class Main
public static void main(String[] args)
// write your code here
NumUtil un = new NumUtil();
int sum = un.sum();
System.out.println(sum);
class NumUtil
private int tmp = 0;
public int sum()
for (int i =0 ;i<=100;i++)
tmp = tmp + 1;
return tmp;
在上面的传递方式中,方法中都有一个默认值,作为初始值,也可以自定义初始值:
public class Main
public static void main(String[] args)
// write your code here
NumUtil un = new NumUtil();
int sum = un.sum();
System.out.println(sum);
class NumUtil
private int tmp = 0;
public int sum(int a)
tmp = a;
for (int i =0 ;i<=100;i++)
tmp = tmp + 1;
return tmp;
sum(int a)
中传递了一个名为a大的变量,在其数据类型是int,那么在调用该函数时传递的参数就必须时int类型。
不同语言的规范不一样,定义的规则也一样,传递的规则也是。例如,在C语言中int i;
就是表示定义了一个int内置类型的变量,名称为i;在Java中String name
就是定义了一个名为name的String类型;这些是强类型语言的定义,像js,python等弱类型语言的定义方式又不一样a = 1
是python定义变量的方式,a可以是是任意类型,最终类型又开发者赋予的值类决定。在js中提供了val,let,const定义局部和全局变量,且也是自动类型推断。在许多后来的语言中都有局部变量和全局变量的关键字定义,例如在scala中,var a :String = "_小许_"
等等。
如下为常见的变量定义:
//c语言变量定义
int i, sum=0;
//变量传递
//java
String name = "";
# python
a = 0;
//go
a := 0
函数的定义在强类型语言中必须要声明类型,如在函数定定义局部变量,在函数的参数中定义变量,而在若类型的语言中,定义变量不需要声明类型,但是必须要有初始值,由编译器或者解析器推断类型。
有些语言如Scala提供了var,val
等一些关键字,Go的var,const
关键字来区别于局部变量和常量,这些只在方法体内生效。(方法的参数是方法的一部分,不能使用这些关键字)。
总的来说,函数的变量可以分为:局部变量,全局变量,形式变量。
- 函数内定义的变量称为局部变量
- 函数外定义的变量称为全局变量
- 函数定义中的变量称为形式参数
在函数体内声明的变量称之为局部变量,它们的作用域只在函数体内,函数的参数和返回值变量都属于局部变量。局部变量不是一直存在的,它只在定义它的函数被调用后存在,函数调用结束后这个局部变量就会被销毁。
//go
func addNum(a int,b int) int
y := 3*a+4*b;
return y
//java
public class Util
public int addNum(int a,int b)
int y = 3*a + 4*b;
return y;
y均为局部变量。
在函数体外声明的变量称之为全局变量,全局变量只需要在一个源文件中定义,就可以在所有源文件中使用。有些语言变量必须定义在类中如Java,有的语言可以定义在源文件中,如Go在外部包中使用全局变量的首字母必须大写。
//go语言
package main
import "fmt"
//声明全局变量
var c int
func main()
//声明局部变量
var a, b int
//初始化参数
a = 3
b = 4
c = a + b
fmt.Printf("a = %d, b = %d, c = %d\\n", a, b, c)
//java
public class Person
private int id;
private String name;
private Double price;
在定义函数时函数名后面括号中的变量叫做形式参数(简称形参)。形式参数只在函数调用时才会生效,函数调用结束后就会被销毁,在函数未被调用时,函数的形参并不占用实际的存储单元,也没有实际值。
//go
func operation(n int, m int) (int, int, int, int)
return n + m, n - m, n * m, n / m
//java
public class Person
private int id;
private String name;
private Double price;
public void setId(int id)
this.id = id;
public int getId()
return this.id;
public void setName(String name)
this.name = name;
public int getName()
return this.name;
public void setPrice(Double price)
this.price = price;
public Double getPrice()
return this.price;
你真的了解JavaScript吗
第一题
其实就是变量提升的概念
var a;
if(!(\'a\' in window)){
a = 1;
}
console.log(a);
第二题
这里就是函数声明会覆盖变量声明了; 即使函数声明写在变量声明的后面。也会覆盖,但是函数表达式不会覆盖。
第三题
函数上下文中的变量对象一节就可以清楚地知道,活动对象是在进入函数上下文时刻被创建的,它通过函数的arguments属性初始化。arguments属性的值是Arguments对象:
Arguments对象是活动对象的一个属性,它包括如下属性:
- callee — 指向当前函数的引用 arguments.callee.length 就是形参个数 也可以使用函数名字.length; 其实 funName.length === arguments.callee.length;
- length — 真正传递的参数个数
- properties-indexes (字符串类型的整数) 属性的值就是函数的参数值(按参数列表从左到右排列)。 properties-indexes内部元素的个数等于arguments.length. properties-indexes 的值和实际传递进来的参数之间是共享的。
这个共享其实不是真正的共享一个内存地址,而是2个不同的内存地址,使用JavaScript引擎来保证2个值是随时一样的,当然这也有一个前提,那就是这个索引值要小于你传入的参数个数,也就是说如果你只传入2个参数,而还继续使用arguments[2]赋值的话,就会不一致,例如:
第四题
根据ECMAScript262规范规定:如果第一个参数传入的对象调用者是null或者undefined的话,call方法将把全局对象(也就是window)作为this的值。所以,不管你什么时候传入null,其this都是全局对象window。如果是alert(this); 就是 ‘[object Window]’;
以上是关于你真的了解变量吗?的主要内容,如果未能解决你的问题,请参考以下文章