004 - 深入理解Js中原型链和继承

新世纪的编程语言中,面向对象可以说是极大方便了开发者,身为后起之秀的javascript,更是借鉴更新,形成了一种具有自己特点的面向对象的方式,巧妙的用了 “基于原型的继承方式”,不必纠结于什么是原型,去想一下,为什么这么设计,就会发现,这是多么巧妙

了解Js继承,就先明白 “为什么说 Js是基于原型链的语言”, 下边先简单介绍一下,Js是如何设计的

Js如何解释prototype

JavaScript 中的每个函数中都有 prototype 属性, 这是Js中函数的一个属性 ,是函数独有的一个属性

  var x = function (a, b) {return a * b};
  console.log(x.prototype)   // 输出   {constructor: ƒ}

上边的代码中,可以看到函数有这一个属性,它指向了一个对象,对象有一个constructor属性。在Javascript 资料中 , 说函数的prototype 属性指向的是“函数的原型对象”, 先不要纠结这是啥,它只是一个名字。 关注一下这个原型对象用处 :

“包含可以由特定类型的所有实例共享的属性和方法”
函数和创建对象

之前文章中提到,利用函数创建对象,

 var x = function (a, b) {return a * b};
 var xbj =  new x();
console.log(xbj); //输出 :{}

上边代码,利用new操作符 ,来调用构造函数,会创建一个对象,其中this可以指向调用函数之后创建的对象。 这里简单说一下,new操作符是用来创建对象,并不是调用函数本身,如下

	var person = function (a, b) {
	    this.name = a;
        this.age = b;
    };
    var zhangsan = new person('zhangsan',21);
    console.log(zhangsan);
    //输出 :person {name: 'zhangsan', age: 21}
    console.log(typeof zhangsan); //输出 :“object”
    var lisi =  new person('lisi',18);
    console.log(lisi);  //输出 : person {name: "lisi", age: 18}

上边创建了 zhangsan和lisi两个对象,输出也证明了这一点

从设计师角度考虑,如何使用原型对象

之前的代码,了解了构造函数会有原型对象,构造函数可以创建对象。接下来,倘若构造函数创建的多个对象都需要添加 几个共同属性,比如zhangsan 和lisi 中新增一个属性 country : ‘china’

当然 ,可以直接添加

  zhangsan.country = 'china';
  lisi.country = 'china';

但是, 试想一下,这只是两个人,假如一百个人,一千个人呢, 在Java中,会考虑把这些多个对象共用的变量放到类的静态量中,实际上,Javascript 也用了有点类似的方式,Javascript是用构造函数创建对象,把多个对象共用的变量放到 构造函数的 原型对象 prototype中,如下

person.prototype.country = 'china'
console.log(lisi.country);	 //输出 china
console.log(zhangsan.country); // 输出 china
了解函数的原型对象

函数的原型对象, prototype ,其中有一个属性constructor 。 javascript是这样描述:

constructor属性 : 是对象特有的属性,指向这个对象的构造函数, 每个对象都会有,有意思的是,Javascript中 一切都是对象,如下

var obj = {};
var arr = [];
var f = function(){}
console.log(obj.constructor)
//ƒ Object() { [native code] }
console.log(arr.constructor)
//ƒ Array() { [native code] }
console.log(f.constructor)
//ƒ Function() { [native code] }

上边代码也佐证了一切对象都会有构造器属性 constructor 。 仔细观察,constructor属性实际上是指向了每个对象的构造函数,比如{}的构造函数是Object 、[]的构造函数是 Array、函数的构造器函数是 Function

接下来看一下,如果是用new 创建的对象,它的构造函数是:

var person = function(){this.name = '123'};
var bob = new person();
console.log(bob.constructor); //输出 : ƒ (){this.name = '123'}
var tom = new bob.constructor() // 测试用bob对象的constructor属性是否可以创建对象
console.log(tom)//person {name: "123"}

再一次证明了,每个对象都有 constructor属性,指向的是它的构造函数。实际上 这也要求,我们如果想修改两个构造函数创建的对象的父子关系,不要忘了修改 “函数原型对象的constructor属性”

_proto_

创建的对象,我们注意到除了自身属性之外,也有一个_proto_属性,它指向一个对象。
创建的对象有

"_proto_是Js中对象特有的,指向的是它的原型对象"

注意 Js中对象都会有这么一个属性,因此 , 原型对象也会有自己的这一个属性,指向原型对象它的 原型对象 。形成了一个链的东西,就是原型链在这里插入图片描述

说一下 , 原型链

上边截图中,可以清楚看到了原型链,原型链就是

对象中的_proto_,层层上推,一直到顶层Object

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值