“一切都是对象”这句话的重点在于如何去理解“对象”这个概念。
——当然,也不是所有的都是对象,值类型就不是对象。
在谈对象之前,首先咱们还是先看看javascript中一个常用的函数——typeof()。typeof应该算是咱们的老朋友,还有谁没用过它?
typeof函数输出的一共有几种类型,在此列出:
function show(x) {
console.log(
typeof(x));
console.log(
typeof(
10));
console.log(
typeof(
'abc'));
console.log(
typeof(
true));
console.log(
typeof(
function () { }));
console.log(
typeof([
1,
'a',
true]));
console.log(
typeof ({ a:
10, b:
20 }));
console.log(
typeof (
null));
console.log(
typeof (
new Number(
10)));
}
show();
以上代码列出了typeof输出的集中类型标识,其中上面的四种(undefined, number, string, boolean)属于简单的值类型,不是对象。剩下的几种情况——函数、数组、对象、null、new Number(10)都是对象。他们都是引用类型。
*判断一个变量是不是对象非常简单。值类型的类型判断用typeof,引用类型的类型判断用instanceof。
var fn =
function () { };
console.log(fn
instanceof Object);
对象——若干属性的集合
对象是什么?在java或者C#中的对象都是new 实例化出的,而且里面有字段、属性、方法,规定的非常严格。但是javascript就比较随意了——数组是对象,函数是对象,对象还是对象。对象里面的一切都是属性,只有属性,没有方法。那么这样方法如何表示呢?——方法也是一种属性。因为它的属性表示为键值对的形式。
而且,更加好玩的事,javascript中的对象可以任意的扩展属性,没有class的约束。这个大家应该都知道,就不再强调了。
那么函数和数组也可以这样定义属性吗?——当然不行,但是它可以用另一种形式,总之函数/数组之流,只要是对象,它就是属性的集合。
例如:
var fn =
function () {
alert(
100);
};
fn.a =
10;
fn.b =
function () {
alert(
123);
};
fn.c = {
name:
"芷若初荨",
year:
1994
};
上段代码中,函数就作为对象被赋值了a、b、c三个属性——很明显,这就是属性的集合。
有些朋友或者会问,看这些有什么用呢?其实大家如果学到了JQuery,想要看懂JQuery源码,那么这个就会起到很大的作用。在jQuery源码中,“jQuery”或者“$”,这个变量其实是一个函数。
所以一切(引用类型)都是对象,对象是属性的集合。
函数和对象之间的关系
函数就是对象的一种,因为通过instanceof函数可以判断,但是函数与对象之间,却不仅仅是一种包含和被包含的关系,函数和对象之间的关系比较复杂。
但有一点是可以肯定的,对象都是通过函数来创建的,可是这是为什么呢?大家看下面一个实例就知道了。如:
var obj =
new Object();
obj.a =
10;
obj.b =
20;
var arr =
new Array();
arr[
0] =
5;
arr[
1] =
'x';
arr[
2] =
true;
输出结果:
console.log(
typeof (
Object));
console.log(
typeof (
Array));
原型Prototype
既typeof之后的另一位老朋友!
prototype也是我们的老朋友,即使不了解的人,也应该都听过它的大名。
刚刚谈到函数是一种对象,也是属性的集合,我们可以对函数进行自定义属性,JS默认就给函数提供了一个属性——Prototype,这个prototype的属性值是一个对象,这个prototype的属性值是一个对象(属性的集合,再次强调!),默认的只有一个叫做constructor的属性,指向这个函数本身。
每个对象都有一个*__proto__属性,指向创建该对象的函数的prototype。
在说明“Object prototype”之前,先说一下自定义函数的prototype。自定义函数的prototype本质上就是和 var obj = {} 是一样的,都是被Object创建,所以它的proto指向的就是Object.prototype。
但是Object.prototype确实一个特例——它的proto指向的是null,切记切记!
对象的proto指向的是创建它的函数的prototype,就会出现:Object.proto === Function.prototype。用一个图来表示。
上图中,很明显的标出了:自定义函数Foo.proto指向Function.prototype,Object.proto指向Function.prototype,形成一个循环引用。其实稍微想一下就明白了。Function也是一个函数,函数是一种对象,也有proto属性。既然是函数,那么它一定是被Function创建。所以——Function是被自身创建的。所以它的proto指向了自身的Prototype。
那么Function.prototype指向的对象,它的proto是不是也指向Object.prototype?
答案是肯定的。因为Function.prototype指向的对象也是一个普通的被Object创建的对象,所以也遵循基本的规则。
以上纯属个人在查询相关资料和看视频后的理解,如有错误,请指正,谢谢!
转载请注明原文地址: https://www.6miu.com/read-758.html