Javascript 的型别可以分为两大类,分别是 原始型别 以及 物件型别
我们经常会使用这些型别各自的方法, 例如用 length
取得字串的长度。
但为什么明明是 基本型别 却会有 属性 以及 方法 可以呼叫?
这是因为这些型别有着相对应的 包裹物件 (Primitive Wrapper),这些 包裹物件 包含了这些物件可以使用的方法,我们接着会在物件型别中做更多说明。
原始型别
先来看关于原始型别的範例程式码:
let a, b, c, d, e;a = 1; //numberb = '文字'; //stringc = true; //booleand = {}; //objecte = null; //objectconsole.log(typeof(a));
console.log(f); // VM1420:1 Uncaught ReferenceError: e is not definedconsole.log(typeof(f)); // undefined
值得注意的是:
e 虽然被指派为null
,但型别却是 object
,这是 js 长久以来的一个错误,没有修正是因为许多的网站也使用了这样的错误观念完成了网站。如果修正的话会造成许多的网站因此而坏掉,所以就把这个错误保留了下来。f 这个未定义的变数的型别是 undefined
, 这是 typeof
保护机制,如果在没有定义 f 这个变数的情境下 console.log
的话,会出现的是 not defined
现在来看另一段範例:
let a = 'ming ';console.log(a.length); // 5console.log(a.toUpperCase()); // MING console.log(a.trim()); // ming
上述这些方法都是针对字串所做的,但是直接 console.log(a)
; 也只有显示 'ming ',并没有显示那些可以用的方法,而 包裹物件 则可以做得到。
物件型别
前面提到,基本型别会有「属性」以及「方法」是因为这些型别有着相对应的包裹物件 (Primitive Wrapper)。
也就是「自动转型」赋予 String
、Number
与 Boolean
这些神奇的功能。
在 JavaScript 这门程式语言当中,当我们尝试着要去存取 String
、Number
与 Boolean
这三种基本型别的属性时,它就只会在「那一刻」被转型为该类别的「物件」。
let a = 'ming ';console.log(a.length);
上面段程式码,当我们试着去读取 a.length
的时候,背后原理是这样的:
let a = new String('ming ');a.length;a = null;a = 'ming ';
它会透过对应的物件建构器将 'ming ' 包装成一个 String 的「物件」,然后回传对应的属性后,即刻销毁恢复成基本型别。
我们可以透过下面这段程式码来了解 原始型别 与 物件型别 的不同。
let a = 'ming ';let e = new String(a);console.log(a, e);
我们可以透过下面这段程式码来了解 原始型别 与 物件型别 的不同。
a 是一个原始型别为字串的变数。e 是一个透过建构式建立的物件。透过这样的方式宣告之后,来看看执行的结果:
可以看到 [[prototype]] 就是 e 这个包裹物件的可以用的方法总集
同样可以套用原是型别的字串身上,所以我们刚刚用的 trim
lengthto
UpperCase
都在这里面喔!
然而,其实并不建议在宣告字串的时候使用字串的 包裹物件 方式宣告,这种宣告方式又称为 建构式
后续的篇章会讲到,而不建议的最大重点在于,透过建构式宣告出来的变数资料型别不会是字串,而是 物件 喔!
参考文章