在js中,对于对象的理解很重要。
js的数据类型主要分为基本类型和引用类型。基本类型包括String
、Number
、Boolean
、undefined
、null
。引用类型包括Object
。
通常判断一个数据类型是基本类型可以使用typeof
,判断一个数据类型是引用类型的可以使用instanceof
。
本文要讲的其实就是基于引用类型对象来说的。所谓的对象其实可以理解为若干属性的集合。狭义的对象object
是对象,Function
也是对象,Array
同样也是对象。
object
对象可以自由添加属性和方法是众所周知的,那么Function
和Array
可以使用同样的方法添加属性和方法么?
1var fn = function(){
2 console.log(100);
3}
4fn.a = 20; //函数fn添加属性a
5fn.b = function(){ //函数fn添加方法b
6 console.log('aaa');
7}
8fn.c = { //函数fn添加属性c, c的值是个对象
9 a: 29
10}
11console.log(fn);
12console.log(fn.a);
13console.log(fn.b());
14console.log(fn.c);
15
16//打印
17/*
18ƒ (){
19 console.log(100);
20}
21b1.html:25 20
22b1.html:19 aaa
23b1.html:26 undefined
24b1.html:27 {a: 29}
25*/
上例就是函数添加属性和方法。至于向数组添加属性和方法,在实际工作中数组的方法使用的应该不少了吧,比如concat
、slice
之类的,所以结论是只要是对象,js中都可以自由添加属性和方法。
现在我们明确知道,函数就是对象的一种。但函数和对象其实有种鸡生蛋蛋生鸡的感觉。因为对象的创建var obj = {a:1}
的本质行为是:
1var obj = new Object();
2obj.a = 1;
3
4var arr = new Array();
5arr[0] = 10
6
7console.log(typeof Object); //function
8console.log(typeof Array); //function
可以很明确的看到,狭义对象或数组本质上都是通过函数来创建出来的。此时我又要祭出我珍藏已久的JS万物图了,相信筒子们可以图中理解Function和Object之间的互相关系了。
其实函数本身就是有属性的,无需通过上文举例来证明函数可以添加属性,这个函数的已有属性就是prototype
。
1var Fn = function(){}; //定义构造函数Fn
2Fn.prototype.getStatus = function(){}; //在构造函数Fn的原型上添加getStatus方法
3var fn = new Fn(); //通过构造函数Fn进行new出来一个实例对象fn,
4
5//fn的原型链指向Fn的原型
6//即:fn.__proto__ === Fn.prototype
每个函数function
都有一个原型属性,即prototype
。每个对象都有一个隐式原型链,即__proto__
,对象的__proto__
指向该对象构造器的prototype
原型。
1var obj = new Object();
2console.log(obj.__proto__ === Object.prototype); //true
上例可以用一个图来表示:
这里有一个问题,js中所有对象其实最终都指向Object.prototype
,那么这个Object.prototype
又指向哪里呢?指向null
看图:
所以结合上面几个图,可以形成这样一个结论:
在JS世界中,
null
为开始,由null
开始衍生出Object.prototype
。Object.prototype
的隐式原型链指向null
。正向来说Object.prototype
是构造函数Function Object()
的原型prototype
,反过来说Object.prototype
的构造器constructor
也是构造函数Function Object()
。这里Object.prototype
和Function Object()
的关系比较容易混淆,但请认真记住。
下面给出完整原型图:
从上图可以看出一个关系,那就是js中的各对象间都是通过原型链来互相连接起来的,这个原型链将所有对象链接在了一起,这就是为什么说JS是基于原型的面向对象编程语言,即使现在有es6 7有了class类,它本质上也是基于原型链形成的语法糖而已。
js中实现的继承就是通过这条原型链来工作的:在访问一个对象的某个属性时,先该对象的现有属性中查找,如果没有,再沿着__proto__
这种链向上找,这就是原型链。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有