Javascript浅谈之引用类型

简介
1.引用类型(Reference type)
引用类型是javascript中一种内部类型。它主要是当做一个指代,代替一个变量或者函数,当然在需要真实值时,又可以通过它寻找到真实值。

2.引用类型的结构
引用类型的值时由两部分构成,一是引用类型的值指代的对象的所属对象,这里我们姑且把它叫做base,二是base中的指代对象的对象名称。用伪代码来表示:

代码如下:

var valueOfReferenceType = {
base: <base object>,
propertyName: <property name>
};

3.使用情景
引用类型的使用情景有二:

(1)在处理一个标示符时

标示符是变量名,函数名,函数参数名和全局对象中未识别的属性名。

(2)在处理一个属性访问器时

代码如下:

var foo = 10;
function bar( ){}

在操作的中间结果中,引用类型对应

代码如下:

var fooReference = {
        base: global,
        propertyName: 'foo'
    };

var barReference = {
        base: global,
        propertyName: 'bar'
    };

这里还是有必要解释一下base,在javascript中所有对象或者函数都有所属对象,看过我前面文章的人都知道,在每个执行上下文有个变量对象专门来管理这个执行上下文中的变量或者函数。

所以,当处理标示符时:

在全局上下文中,毋庸置疑,base === globalVO === gloabal

在函数的执行上下文中,base === VO/AO

但处理对象属性是:

这个更是简单,base === owerObject

4.获取引用类型的真正值
一开始我们说了,引用类型只是一个指代,而不是它并不保存真正的值。当需要真正的值时,可以通过内部一系列算法,可以得到。这个算法,我们可以用简单的伪代码来描述:

代码如下:

function GetValue(value) {

if (Type(value) != Reference) {
    return value;
  }

var base = GetBase(value);

if (base === null) {
    throw new ReferenceError;
  }

return base.[[Get]](GetPropertyName(value));

}

内部的[[Get]]方法返回对象属性真正的值,包括对原型链中继承的属性分析。所有通过GetValue我们也可以轻松获取引用类型的真正的值。如下例:

代码如下:

GetValue(fooReference); // 10
GetValue(barReference); // function object "bar"

那我们什么时候需要获取引用类型的真正值呢?

一般是在引用类型需要进行赋值、参与运算或者被调用是需要通过GetValue方法获取真正值。(注意:通过GetValue获取到的对象不再是引用类型)

引用类型与this的关系
引用类型主要是跟函数上下文中的this指向关系密切,且不同时候看起来还差异挺大,所有我们才引出引用类型来专门解释函数上下文中this的表现。

函数上下文中确定this值的通用规则如下:

在一个函数上下文中,this由调用者提供,由调用函数的方式来决定。如果调用括号()的左边是引用类型的值,this将设为引用类型值的base对象(base object),在其他情况下(与引用类型不同的任何其它属性),这个值为null。不过,实际不存在this的值为null的情况,因为当this的值为null的时候,其值会被隐式转换为全局对象。注:第5版的ECMAScript中,已经不强迫转换成全局变量了,而是赋值为undefined。

下面我们根据调用括号左边不同分三种情况进行讨论:

(1)调用括号左边是引用类型的值

这无需作过多分析,base对象就是this值,找到base即可。如果是全局变量下申明的,那就指向全局对象。

代码如下:

var myObject = {
     foo : function(){
            console.log(this);
      } 
}

myObject.foo(); //毫无疑问,这个foo的base是myObject,故foo方法中的this指向myObject。

(2)调用括号左边是引用类型的值,不过这个值为null

代码如下:

function myFunction() {
     var foo = function(){
            console.log(this);
      } 
       foo();    //AO.foo() => null.foo()
}

myFunction(); //输出:Window {top: Window, window: Window...}

当一个内部函数被调用时,这个内部函数的base应该是当前执行上下文中活动对象(OA),但是在javascript内部在OA作为base时,都当做null处理,javascript当然不允许this为null的情况发生,所有就将base设置为global对象(这是前文this函数调用模式中设计错误的源头)。所以在这情况下,this都指向全局对象。

(3)调用括号左边不是引用类型的值

代码如下:

//简单点的例子
(function () {
  console.log(this); // null => global
})();

//复杂些的例子
var foo = {
  bar: function () {
    console.log(this);
  }
};

foo.bar(); // Reference, OK => foo
(foo.bar)(); // Reference, OK => foo

(foo.bar = foo.bar)(); // global
(false || foo.bar)(); // global
(foo.bar, foo.bar)(); // global

当调用括号的左边不是引用类型而是其它类型,this自动设置为null,结果为全局对象。

第一个例子中,立即函数,它的函数调用小括号左边是一个表达式,不是一个引用。

第二个例子复杂了许多,我们来一个个分析:

foo.bar(),这个没有疑问,base为foo,this指向foo。

(foo.bar)(),这里用到了一个小括号,它在这起到分组符作用,也就是它不会迫使引用类型执行GetValue方法,其执行结果,跟上面一模一样。

后面三个,小括号里面依次是赋值运算、或运算和逗号运算,它们都会迫使引用类型执行GetValue方法,从而返回一个函数对象。这样,函数调用小括号左边就不再是引用类型了,所有,this都是指向全局对象的。

总结

关于引用类型,其实我都一直不太了解这个,只是看到汤姆大叔的博客中this那章,为了解释函数调用模式中this的取值原理且专门分析了一下,这一分析可不得了,我之前一直认为引用类型和引用传值应该存在某些关系,没想到,它大叔bolg中只是用来辅助理解this。至于他们二者之前有没有关系,如果有关系到底是一种什么关系,这还得我继续学习研究。

希望大家多交流。在此还是的感谢汤姆大叔.

(0)

相关推荐

  • JavaScript中“基本类型”之争小结

    前端面试中常被问到的问题之一就是"JavaScript的基本类型有几种?". 有的回答"数字.字符串.布尔",有的可能会再加上"Null.Undefined".而有人可能认为"object"也是基本类型.到底是什么样呢? 所谓"基本类型(primitive types)"的概念ECMAScript(V3,V5)中压根就没有,它只是将类型分为6种. ECMAScript只提到类型,用types表示,在V3,V

  • 浅析JavaScript基本类型与引用类型

    对于 JavaScript 类型,可以简单地概括为:相对于强类型语言来说,它是弱(松散)类型的语言:有基本类型和引用类型,他们是区别是一个有固定空间存在于栈内存中,一个没有固定空间保存在堆内存中并且在栈内存中保存了一个指向实现位置的指针. 市面上很多书都有不小的篇幅在讲.这篇文章会讲几个方面,这些方面可能会需要你对 JavaScript 已经有了一些简单的了解,特别是 JavaScript 的类型.如果还不一解,可以随手拿起一本关于 JavaScript 的书翻翻,再来看本文. 一.基本类型与引

  • 跟我学习javascript的基本类型和引用类型

    一.基本类型和引用类型 基本的数据类型有5个:undefined,boolean,number,string,null typeof null; //"object" typeof undefined; //"undefined" typeof 1; //"number" typeof false //"boolean" typeof "1" //"string" (令人困惑的是,对nu

  • 《JavaScript高级编程》学习笔记之object和array引用类型

    本文给大家分享我的javascript高级编程学习笔记之object和array引用类型,涉及到javascript引用类型相关知识,大家一起看看把. 1. Object类型 大多数引用类型值都是Object类型的实例:而且Object也是ECMAScript中使用最多的一个类型. 创建Object实例有如下两种方式: new操作符后跟Object构造函数: var person=new Object( ); person.name="webb"; person.age=25; 对象字

  • Javascript delete 引用类型对象

    如下面例子: 复制代码 代码如下: var testVar = {            a : {                test : 1            }        },            test1 = {},            test2 = {}; test1.a = testVar.a;        test2.a = testVar.a;/*        delete test1.a;        console.log(test1.a); //

  • javascript基本类型详解

    js中一共5个原始值,6个typeof能判断的,9个原生的内置的构造函数. 这569,构成了js语言的基础. 5个原始值是:数字,字符,布尔,null,undefined typeof能判断:数字,字符,布尔,object,function,undefined. 注意null和数组,tyopeof都输出object. typeof不能区分出数组和对象,如何判断类型呢?使用Object.prototype.toString.apply(). if(value&&typeof value ==

  • javascript引用类型指针的工作方式

    先看个例子: <script> var a = {n:1}; var b = a; a.x = a = {n:2}; console.log(a.x);// --> undefined console.log(b.x);// --> [object Object] </script> 上面的例子看似简单,但结果并不好了解,很容易把人们给想绕了--"a.x不是指向对象a了么?为啥log(a.x)是undefined?"."b.x不是应该跟a.

  • JavaScript之引用类型介绍

    Object类型 Object类型是JavaScript中使用最多的一种类型.虽然Object的实例不具备多少功能,但对于在应用程序中存储和传输数据而言,它确实是非常理想的选择. 创建Object实例的方式有两种,第一种是使用new操作符后跟Object构造函数. 复制代码 代码如下: var person = new Object(); person.name = "tt"; person.age = 12; 另一种方式是使用对象字面量表示法. 复制代码 代码如下: var pers

  • JavaScript数据类型之基本类型和引用类型的值

    ECMAScript变量包含两种不同数据类型的值:基本类型值和引用类型值.基本类型值是简单的数据段,而引用类型值指那些可能由多个值构成的对象. 在将一个值赋给变量时,解析器必须确定这个值是基本类型还是引用类型.基本类型包括如Undefined.Null.Boolean.Number和String,这5种基本类型数据类型是按值访问的,因此可以操作保存在变量中的实际的值:引用类型类型的值是保存在内存中的对象.与其他语言不同,JavaScript不允许直接访问内存中的位置,也就是说不能直接操作对象的内

  • JavaScript中值类型与引用类型实例说明

    复制代码 代码如下: <script type="text/javascript"> var str = 'abced'; var obj = new String(str); function newToString() { return 'hello,world'; } function func(val) { val.toString = newToString; } func(str); //ps:实际只传入了str的值,因此对它的toString修改是无意义的 传

  • javascript中基本类型和引用类型的区别分析

    基本类型和引用类型 ECMAScript包含两个不同类型的值:基本类型值和引用类型值.基本类型值指的是简单的数据段:引用类型值指由多个值构成的对象.当我们把变量赋值给一个变量时,解析器首先要做的就是确认这个值是基本类型值还是引用类型值. 常见的五种基本数据类型是: Undifined.Null.Boolean.Number和String.这五种基本数据类型可以直接操作保存在变量中的实际值. 看下面例子: var a = 10; var b = a; b = 20; console.log(a);

  • javascript引用类型之时间Date和数组Array

    Javascript引用类型之时间Date JavaScript中的Date类型是在早期Java中的java.util.Date类基础上构建的.为此,Date类型使用自UTC 1970年1月1日零时开始经过的毫秒数来保存日期.在使用这种数据存储格式的条件下,Date类型保存的日期能够精确到1970年1月1日之前或之后的285 616年. 创建日期对象 在javascript中,可以使用Date()构造函数来创建日期对象,如: 复制代码 代码如下: var date=new Date(); 当没有

  • 《JavaScript高级程序设计》阅读笔记(三) ECMAScript中的引用类型

    2.8 引用类型 1.Object类 ECMAScript中的所有类都是由Object类继承而来. Object类具有下列属性: Constructor:对创建对象的函数的引用(指针),对于Object类,该指针指向原始的Object()函数 Prototype:对该对象的对象原型的引用. Object类还有几个方法: HasOwnProperty(property):判断对象是否有某个特定的属性.必须用字符串指定该属性值 IsPrototypeOf(object):判断该对象是否为另一个对象的

随机推荐