关于变量与属性

这个问题很基础了,其实在JavaScript中变量和属性的含义跟其他命令式的语言(纯函数式语言没有变量)没有区别。

其实变量和属性的共同点很明显,就是都可以存储数据,并且可以通过一定的途径来访问,大部分的情况下,我们也都是这么使用它们的,但是随着对JavaScript学习的深入,问题就随之而来了,那么它们有什么区别呢?它们是一样的吗?

下面我们看看它们的主要区别:

为了方便描述,我们给变量取名叫variable, 给属性取名attr,并且指定一个前提:JavaScript只有函数是可以运行的,也就是说全局范围内写的JavaScript代码我们都假定它们写在一个浏览器提供的最外层的函数里面。

1. 定义方式

  a.变量是在函数定义中通过var variable定义的

    这里面需要注意两点,一个是变量只在函数定义中声明,当然这里我们用了前面假定的前提。二是只能通过var关键字来定义。

  b.属性是通过this.attr或者objName.attr来定义的,或者attr定义的(.操作符可以换成[""])

2. 访问方式

  2.1 可访问性

    a.变量:闭包中包含此变量的函数可以对此变量进行访问(后续文章会对此作出更详细的解释)

    b.属性:只要有对象的引用(包括this),就可以通过对象来访问属性

  2.2 delete操作

    a.变量不能被delete

    b.属性可以delete

3. 归属

  a. 变量:归属于执行上下文(Execution Context)的变量对象(Variable Object)

  b.属性: 归属于所在对象

下面就归属问题详细聊一下。

总是感觉JavaScript研究深入的时候,有很多刚入门的时候看似很简单,很浅显的问题,追究起来,就变得不那么简单了。

属性其实比较简单,它就归属于它所在的对象,不管在什么场景,什么情况下,对象内部都可以通过this.attr来定义或访问变量,对象外部都可以通过对象的引用 objName.attr来定义或访问变量。

而变量就相对复杂一些,从外面看来 var attr就声明了一个变量,如果当前函数的作用域链中有attr,就可以访问。如果对Execution Context有了解的话就会知道,其实就会知道变量其实也是一个特殊的属性:变量对象(VO)的一个属性。

如果变量其实也是一个属性的话,那么它如何被访问就很明显了,谁能访问VO,谁就能访问到变量。 那么谁能访问VO?不考虑global的话,就是函数执行的时候,函数的作用域链上有属性所在的VO的话,那么函数就可以访问这个属性。

总结:

其实变量和属性本质上都是属性,只不过在JavaScript引擎上访问它们的方式不一样,可见对象的属性是JavaScript本身提供给开发者的一种访问方式,而变量其实是JavaScript引擎内部不可见对象的属性,所以只能通过JavaScript引擎提供的其他方式来访问,

也就是通过在执行函数时JavaScript引擎自动从函数所在闭包中查找变量的方式来访问。

两个潜规则 = 一个有趣的事情:

1.如果单独声明变量,那么默认会声明称全局对象global的属性。

2.全局对象global的VO是它自己。按照上面我们的结论,变量和属性一个是可见对象的属性,另一个是VO的属性,那么对于global来说,VO是它自己,也就是说它的VO是对外可见的。那么会发生什么事情?

一个有趣的事情:

//浏览器下global是window

var a = "a";

b = "b";

alert(window.a) ; //a

alert(window.b); //b

是不是每本JavaScript的书上都有这样的例子?都会告诉你这是JavaScript的一个规则?但是这是为什么?

现在知道为什么a和b都是window的属性了吧,a是因为它在预执行阶段被放到了VO的属性里面,而VO是global;b是因为它没有指定对象,所以默认声明到了global上。

    

时间: 2024-10-15 00:27:21

关于变量与属性的相关文章

iOS 成员变量,实例变量,属性变量的区别,联系

在ios第一版中: 我们为输出口同时声明了属性和底层实例变量,那时,属性是oc语言的一个新的机制,并且要求你必须声明与之对应的实例变量,例如: 注意:(这个是以前的用法) @interface MyViewController :UIViewController { UIButton *myButton; } @property (nonatomic, retain) UIButton *myButton; @end 在现在iOS版本中: 苹果将默认编译器从GCC转换为LLVM(low leve

JS_ 垃圾回收、变量与属性、作用域链

1.垃圾回收 js的垃圾回收机制不同于java,c等语言需要手工回收,js中的垃圾回收是自动启动的,大致过程:js解释器会判断一个对象是否是可达的,即是否有变量指向它,没有,则启动回收机制,释放该对象占用的内存,eg: 1 var s = "hello world"; 2 var s2 = s.toUpperCase();//创建新字符串:"HELLO WORLD" 3 s2 = s;//"hello world"没有变量指向,占用内存被释放 这

Objective-C Runtime 运行时之二:成员变量与属性

类型编码(Type Encoding) 作为对Runtime的补充,编译器将每个方法的返回值和参数类型编码为一个字符串,并将其与方法的selector关联在一起.这种编码方案在其它情况下也是非常有用的,因此我们可以使用@encode编译器指令来获取它.当给定一个类型时,@encode返回这个类型的字符串编码.这些类型可以是诸如int.指针这样的基本类型,也可以是结构体.类等类型.事实上,任何可以作为sizeof()操作参数的类型都可以用于@encode(). 在Objective-C Runti

Objective-C 实例变量与属性的区别

记得刚学习OC时,对实例变量和属性总是不太清楚. 比如下面代码中在打印Person类对象的名字时,什么时候用带“_”的name,NSLog(@"%@",p1->_name); 什么时候用不带“_”的name,NSLog(@"%@",p1.name); 现在回想起来也是挺有意思的过往,写下自己曾经的迷惘,纪念一下青春?.... 首先,使用实例变量编写代码.以及实例变量赋值要用到getter.setter方法. @interface Person : NSObje

实例变量和属性

实例变量和属性 声明 Person 文件中 @interface Person : NSObject { NSString *_name; //实例变量 } @property(copy) NSString *firstName; //属性 @property(copy) NSString *lastName; @end _name 是实例变量,实例变量是类私有的变量,其他类对象无法直接访问: 写在头文件中的 firstName是属性,public,其他类对象可以直接访问:写在m文件中的属性是p

【转截】iOS成员变量、实例变量、属性变量三者的联系与区别

一.类Class中的属性property 在ios第一版中: 我们为输出口同时声明了属性和底层实例变量,那时,属性是oc语言的一个新的机制,并且要求你必须声明与之对应的实例变量,例如: 注意:(这个是以前的用法) @interface MyViewController :UIViewController { UIButton *myButton; } @property (nonatomic, retain) UIButton *myButton; @end 在现在iOS版本中: 苹果将默认编译

iOS开发中 类、对象、实例变量、成员变量、属性变量等区别和关系

类(class):具有相同属性和行为等同一类元素等总称,类是一个抽象的概念. 区分是类还是对象,看它能否继续被细分. 在OC中,类是表示对象类型的结构体,对象通过类来获取自身的各种信息.类由两个部分组成:*.h和*.m文件组成. *.m文件中 implemention部分是类的实现部分,内部包含类中的各种信息,包括各种实例方法或类方法. 类别( category):是为现有的类添加新方法的方式,通常以"类名称+类别名称"来命名. 类别中不能添加新的实例变量.但是可以在类别中添加属性.

runtime第二部分成员变量和属性

接上一篇 http://www.cnblogs.com/ddavidXu/p/5912306.html 转载来源http://www.jianshu.com/p/6b905584f536 http://southpeak.github.io/2014/10/30/objective-c-runtime-2/ 比较实用的内容都用颜色的字标记,并配有代码,并在末尾放上代码demo. 类型编码(Type Encoding) Objective-C不支持long double类型.@encode(lon

成员变量和属性

一个变量如果只想在当前类中使用,那么只需要让它作为成员变量就可以了. 一个变量如果想在类外使用,则还需要将其作为属性. 上图所示的职业,大脑,眼睛,嘴都属于对象的特征,大脑,眼睛和嘴是成员变量,职业就可以看做属性. 成员变量的声明方式: @interface People : NSObject { NSString *_peopleName; int _peopleAge; int _peopleSex; } 一般来说,成员变量是不可以在外部类进行调用的,但是如果在声明成员变量时候加上@publ

170421、maven自定义变量及属性

一.自定义变量 <!-- 全局属性配置 --> <properties> <project.build.name>tools</project.build.name> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> project.build.name: 用来定义war包名称 project.build.sou