什么叫引用类型?
是一个抽象的集合概念,是一个把数据和功能组织在一起的结构
它也被称为对象定义
他们描述了自己的对象应有的属性和方法
对象被认为是某个特定引用类型的实例
例如:
let obj = new Date()
obj就是Date引用类型的一个实例
js有很多自带的基本引用类型如Date、RegExp(相对于Perl有局限)
原始值包装类型:Boolen、Number、String
原始值包装类型,说俗点就是把原始值包装成引用值,它就是一类特殊的引用类型而已
实例化原始值包装类型很简单 let numObj = new Number(233)
(其实就是显示地去构造非对象的变量)
我们看到前面这个例子:
let name1 = "lpj";
let name2 = new String("lpj")'
name1.age = 19;
name2.age = 19;
console.log(name1.age);//undefined name1类型为string
console.log(name2.age);//19 name2类型为object
显然,试图给string类型变量加上属性不符合语法,但是,如果是这样:
let s1 = "some text"
let s2 = s1.substring(2)//成功赋值
实际上,这包含了以下过程:(将非对象临时对象化)
let s1 = new String("some text");//临时切换成对象
let s2 = s1.substring(2);//调用原型链方法
s1 = null;//销毁实例
//另外,如果你一开始就构造的话,是没这么多事的
let str = new String("something");
str.sb = 'kkp';
console.log(str.sb)//kkp
js红宝书说:这是因为“后台进行了很多处理”,我认为,应该指的就是把非对象类型转化为对象后进行原型链的搜索
- 对比详情
引用类型(Date之类)和原始值包装类型主要区别在于生命周期:
通过new实例化引用类型后(也就是上述过程)该实例会被销毁,因此,这解释了为什么name1.age = 19;console.log(name1.age);
是undefined,事实上,第一句会执行上述对象化过程,但被销毁了。事实上后一句执行过程中也创建了String对象(就像let s2 = s1.substring(2);
这一句一样,但发现没有这个属性,所以返回undefined,同样,也会销毁这个实例 - 那么 直接new不就行了吗
是的,但应在确实有必要时才如此操作,否则会使开发者疑惑:这到底是引用值还是原始值 - 此外:
new String('hhh')
和new Object('hhh')
是完全等价的
因为Object构造函数本身是一个工厂模式函数,能够根据输入返回对应原始值包装类型的实例,Number和Boolen同理
总之,这种对象化的行为可以在保持变量为原始值的同时,让原始值拥有对象可继承的特性
小结:通过内置的引用类型,可以创建特定类型的对象,这些对象往往在原型链上有着许多专门编写的属性和方法,比如原始值String变量就是通过原始值包装类型来临时创建对象以访问特殊方法。
单例内置对象以及相关概念
对象类型
先理解下什么是宿主环境:由web浏览器或是桌面应用系统造就的js引擎执行的环境即宿主环境
1、本地对象
ECMA-262 把本地对象(native object)定义为“独立于宿主环境的 ECMAScript 实现提供的对象”。
本地对象包含但不限于Object、Function、Array、String、Boolean、Number、Date、RegExp、各种错误类对象(Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError)
注意:这里的Object、Function、Array等不是指构造函数,而是指对象的类型
2、内置对象
ECMA-262 把内置对象(built-in object)定义为“由 ECMAScript 实现提供的、独立于宿主环境的所有对象,在 ECMAScript 程序开始执行时出现”。这意味着开发者不必明确实例化内置对象,它已被实例化了。ECMA-262 只定义了两个内置对象,即 Global 和 Math (它们也是本地对象,根据定义,每个内置对象都是本地对象)。
当代码执行时,全局作用域就会存在这两个对象了
- Global
全局作用域定义的函数和变量都会变成Global的属性
例如:isNAN()函数,显然它不定义于原型链上,而是在Global上
除了通过window对象来访问,还可以通过let global = function(){return this;}()
(后加()是立即执行函数)
Global其实并不存在(有点哲学)对于web浏览器而言,Global有一个代言人window,但是window并不是ECMAScripta规定的内置对象,因为window对象是相对于web浏览器而言的,而js不仅仅可以用在浏览器中。
- Math
专门放数学公式和操作