一、创建对象的方法
阅读犀牛书(《javascript权威指南》),书中将js创建对象的方法分为四种,对象字面量、构造函数、原型、Object.create()。
1、对象字面量:
需要修改属性只能在对象上修改
var t1 = {x: 1};//也可以写作var t1 = new Object({x: 1});
2、构造函数
需要修改属性也只能在对象上修改,在对象上的修改不会影响到构造器
function f2(){
this.x = 1;
};
var t2 = new f2();//t2创建后,t2的属性不受f2的影响
3、原型
可以通过修改构造器prototype
的值,修改对象的值,但是如果对象上的属性重新赋值了,则在对象上获取的值是重新赋值的值,而不是构造器prototype
的值
function f3(){};
var t3 = new f3();
f3.prototype.x = 1;//如果重新给f3.prototype.x赋值,t3.x也会随之改变
t3.x = 3; //改t3的值重新赋值之后t3.x不会随f3.prototype.x改变
4、Object.create()
可以通过修改父对象的值修改对象的值,重新赋值则无法修改
var f4 = {x: 1};
var t4 = Object.create(f4);//如果f4的属性改变,t4相应的属性也会改变
二、创建的对象的本质
以上四种方法看似不同,但他们的本质是一样的,都是通过最基本的new Object()
与原型来实现对象的创建的。
使用构造器创建对象,其本质如下:
对象的
__proto__
指向了构造器的prototype
,所以修改构造器的属性不会影响对象,但是修改构造器原型会。使用
Object.create()
:
对象的
__proto__
指向了构造器,所以可以通过修改父对象影响对象的属性
三、__proto__
与prototype
__proto__
和prototype
是比较容易混淆的两个属性。__proto__
是对象的属性,用来在原型链上查找你需要的方法的实际对象。prototype
是函数独有的属性当我们使用关键词new
并且将函数作为构造函数来构造对象的时候, 它被用来构建对象的__proto__
属性.
对于非函数的对象来说比较简单只有__proto__
,但是函数也是对象,所以在函数中__proto__
和prototype
同时存在,一个函数作为构造器时,参与其中的是prototype
属性,但是被创建时,__proto__
指向了Function.prototype
。