原型链理解

10 篇文章 0 订阅

配图是网上找的

原型链

构造函数创建对象:

function Person() {

}
var person = new Person();
person.name = 'Kevin';
console.log(person.name) // Kevin

// Person 就是一个构造函数,我们使用 new 创建了一个实例对象 person

prototype

每个函数都有一个 prototype 属性

每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个关联对象即原型(prototype),每一个对象都会从原型中”继承“属性

为了方便理解,将Person构造函数理解为类,将实例化person理解为对象,只有类拥有prototype属性,而对象没有(这里只是个人为了方便理解的一种方式)

function Person() {

}

// prototype是函数才会有的属性
Person.prototype.name = 'Kevin';
Person.prototype.age = '24';
Person.sex = 'boy';

var person1 = new Person();		// 实例化
var person2 = new Person();

console.log(person1.name)       // Kevin
console.log(person2.age)        // 24	每一个成员都会继承原型中的所有属性

proto

每一个JavaScript实例对象(除了 null )都具有的一个属性proto,这个属性会指向该类的原型

对象拥有_proto_属性,指向原型

function Person() {

}
var person = new Person();
console.log(person.__proto__ === Person.prototype); // true  实例化对象的proto属性等于原型

constructor

每个原型都有一个 constructor 属性指向关联的构造函数,实例原型指向构造函数

function Person() {

}
console.log(Person === Person.prototype.constructor); 	// true

图里没画上的线路:对象person可通过constructor得到类Person

原型、类、对象
(这里只是个人为了方便理解的一种方式)

原型

可理解为该类拥有的属性,若一个类想要操作一个属性,不能直接进行操作,必须通过原型来进行(函数对象里声明的变量不是属性),即原型、类、对象的关系可以进一步缩减理解为类和对象之间的关系,原型只是对象拥有的属性,类和对象能通过一些方法(prototype、proto)来访问到这个属性

function Person() {

}
Person.prototype.name = 'Kevin';		// 通过原型
Person.sex = 'boy';						// 直接操作

console.log(Person.prototype)			// Person { name: 'Kevin'}
console.log(Person.sex)					// undefined	直接设置属性失败
console.log(Person.name)				// undefined	直接读取属性失败
console.log(Person.prototype.name)		// Kevin		

声明对象功能并实例化一个对象

对象

每一个对象都拥有类的全部功能,当然也可拥有类的属性,而类的属性存放在原型,通过原型进行操作,因此当对象要拿到类属性,只能在原型中拿(当对象中添加了同名属性时,优先度对象>类),当对象中找不到指定属性时,才会往上层寻找

function Person() {

}

Person.prototype.name = 'Kevin';

var person = new Person();

person.name = 'Daisy';
console.log(person.name) 	// Daisy

delete person.name;			// 删除成员person中刚添加的name属性
console.log(person.name) 	// Kevin

对象、类、原型、Object之间的关系

Object.prototype.age = '24';

function Person() {

}

var person = new Person();
Person.prototype.age_ = '23';

console.log(Person.prototype);   		// Person { age_: 23 }
console.log(Person.prototype.age) 	 	// 上面显示的是原型自己内部的属性,实际自己也继承了Object原型的age 
console.log(Person.age);         		// 24
console.log(person.age_);        		// 23
可以分为两条链路理解:
Object原型 → Object类 → Object对象(Object成员即其他对象的原型)
原型 → 类 → 对象

这样的好处就是只需要记住原型、类、对象的关系三者之间固有的关系即可(加上记住其他类原型即Object三者关系中的对象)

完整的原型链

ES5和ES6

ES5中函数定义类:

function Foo(x,y) {
    this.x = x;
    this.y = y;
}

Foo.prototype.toString = function(){
	console.log(this.x, this.y)  
}

var foo = new Foo(1,2)
foo.toString()  

// 1 2

ES6中定义类:

调用类的方法也就是调用原型(prototype)上的方法

class Foo {   
    constructor(x,y){
     this.x = x;
     this.y = y;
    }
    
    toString(){
     console.log(this.x, this.y)
    }
}

var foo = new Foo(1,2)
foo.toString()  

// 1 2

ES6中,class实际上也是一个function对象,其原型链与es6一致,但有几点需要注意

  • 类里的constructor()方法表示构造函数,与原型链中的.constructor无关
  • 在class中声明的函数会直接添加到原型中,可以直接使用,不需要经过原型
class Foo {   
    constructor(x,y){
     this.x = x;
     this.y = y;
    }
    
    toString(){
     console.log(this.x, this.y)
    }

    
}

Foo.prototype.name = 'Jack'
var foo = new Foo(1,2)

console.log(Foo)                            // Function: Foo]
console.log(foo)                            // Foo { x: 1, y: 2 }

console.log(Foo === foo.constructor)        // true    成员访问对象     foo.__proto__.constructor

console.log(Foo.prototype)                  // Foo { name: 'Jack' }     对象访问原型
console.log(foo.__proto__)                  // Foo { name: 'Jack' }     成员访问原型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值