javaScript中的原型和原型链

131 阅读2分钟

废话

在之前,我一直以为原型就是一个模板,对象根据这个模板创建,相当于拷贝。但是事实上,并不是!对象的原型其实也是一个对象,它的存在是为了让多个对象可以共享一些属性或方法。

附上一篇个人认为非常容易理解的文章:hexianzhi.github.io/2017/04/27/…

prototype属性

构造函数生成实例对象时无法共享一些方法和属性,为了让多个对象共享一些属性和方法,引入了prototype属性,它指向一个对象(也可以叫prototype对象)。

因此一个对象的属性和方法其实分为两种,一种是本地的(将不想共享的属性和方法放在构造函数里),还有一种是引入的(放在原型对象里)。

var f = function(name) {  this.name = name };
f.prototype.getName = function() {return this.name };  //将共享的方法放在prototype对象里
var obj1 = new f('son1');
var obj2 = new f('son2');
obj1.getName();  
obj2.getName(); 

//son1
//son2

getName方法被两个实例对象共享了。

原型链

创建实例对象时会生成一个__proto__指针,指向对象的原型,原型链就是通过这个__proto__指针来实现的。

obj1的__proto__指向f.prototype对象(obj1的原型),而f的prototype对象带有的__proto__指向Object.prototype对象(顶层对象)。

函数也是对象,我们每个创建的函数其实也继承了一个函数对象,而函数则继承了 Object 对象,所以f的__proto__指向Function.prototype,而Function的__proto__指向Object.prototype对象(顶层对象)。

当寻找属性的时候,就先在实例对象找,如果没有找到,就在实例对象的原型上找,而这个原型对象也有它的原型。这样一层层地寻找,就像一条链条将对象之间连接起来,这些链条就是原型链。

三种方法创建对象

1.字面量方式

字面量方式创建对象,它的原型就是Object.prototype(最顶层的原型对象);

var obj = {};
console.log(Object.getPrototypeOf(obj) === Object.prototype);
console.log(obj.__proto__ === Object.prototype);


//true
//true

2.函数的构造调用创建对象

函数的构造调用创建对象,它的原型是这个函数的prototype指向的对象;

var f = function(name) {  this.name = name };
f.prototype.getName = function() {return this.name };
var obj1 = new f('javaScript');
console.log(obj1.getName());
console.log(obj1.__proto__ === f.prototype);

//javaScript
//true

3.Object.create()创建对象

Object.create()创建对象,它的原型是我们传入的对象;

var obj2 = {};
var obj3 = Object.create(obj2);
console.log(obj3.__proto__ === obj2);

//true